C++ 中虚函数的行为
我有一个问题,下面是两个类:
class Base{
public:
virtual void toString(); // generic implementation
}
class Derive : public Base{
public:
( virtual ) void toString(); // specific implementation
}
问题是:
如果我想使用 Base 类型的指针来 Derive 类的子类执行多态性,则 is 关键字括号里的virtual有必要吗?
如果答案是否定的,Derive类的成员函数toString有和没有virtual有什么区别?
I have a question, here are two classes below:
class Base{
public:
virtual void toString(); // generic implementation
}
class Derive : public Base{
public:
( virtual ) void toString(); // specific implementation
}
The question is:
If I wanna subclass of class Derive perform polymophism using a pointer of type Base, is keyword virtual in the bracket necessary?
If the answer is no, what's the difference between member function toString of class Derive with and without virtual?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
C++03 §10.3/2:
C++03 §10.3/2:
该关键字是严格可选的,没有任何区别。
That keyword there is strictly optional and makes no difference at all.
virtual
属性是从基类继承的,即使您没有键入它,也假定它存在。The
virtual
property is inherited from the base class and is assumed to be present even if you don't type it out.编译器已经从基类中的“virtual”关键字知道 toString 是一个虚拟方法。无需重复。
The compiler already knows from the 'virtual' keyword in the base class that toString is a virtual method. No need to repeat it.
函数一旦是虚拟的,就永远是虚拟的。
因此,无论如何,如果在后续类中不使用 virtual 关键字,它不会阻止函数/方法成为“虚拟”,即被覆盖。因此,从团队开发的角度来看,以下指南可能会有所帮助:-
被覆盖,总是使用
“虚拟”关键字。这尤其是
用于接口/基础时为 true
类。
进一步明确地细分
为每个声明“虚拟”关键字
函数/方法可以是
被覆盖。
类不应该是
再次子类化,然后是关键字
“虚拟”需要注释
表明该函数/方法
被覆盖但没有
覆盖它的其他类
再次。这当然不妨碍
有人超越
派生类,除非该类
是最终的(不可导出的),但它
表明该方法不应该是
被覆盖。
例如:
/*虚拟*/ void someFunc();
A function once a virtual always a virtual.
So in any event if the virtual keyword is not used in the subsequent classes, it does not prevent the function/method from being 'virtual' i.e. be overridden. So the following guideline might help from a team development point-of-view :-
be overridden, always use the
'virtual' keyword. This is especially
true when used in interface / base
classes.
be sub-classed further explicity
state the 'virtual' keyword for every
function/method that can be
overridden.
class is not supposed to be
sub-classed again, then the keyword
'virtual' is to be commented
indicating that the function/method
was overridden but there are no
further classes that override it
again. This ofcourse does not prevent
someone from overriding in the
derived class unless the class
is made final (non-derivable), but it
indicates that the method is not supposed to be
overridden.
Ex:
/*virtual*/ void someFunc();
无论您是否在函数的派生版本上提供virtual关键字,对于编译器来说都无关紧要。
然而,无论如何提供它都是一个好主意,这样任何查看你的代码的人都能够知道它是一个虚函数。
It doesn't matter to the compiler whether or not you supply the virtual keyword on derived versions of the function.
However, it's a good idea to supply it anyway, so that anyone looking at your code will be able to tell it's a virtual function.
这是一个良好风格的问题,用户程序员知道发生了什么。在 C++0x 中,您可以使用 [[override]] 使其更加明确和可见。您可以使用 [[base_check]] 强制使用 [[override]]。
如果您不想或不能这样做,只需使用 virtual 关键字即可。
如果您在没有虚拟 toString 的情况下进行派生,并且将 Derive 的实例强制转换回 Base,则调用 toString() 实际上会调用 Base 的 toString(),因为据它所知,这是 Base 的实例。
It's a matter of good style, and the user-programmer knows what's going on. In C++0x you can use [[override]] to make it more explicit and visible. You can use [[base_check]] to force the usage of [[override]].
If you don't want or can't do that, simply use the virtual keyword.
If you derive without virtual toString, and you cast an instance of Derive back to Base, calling toString() would actually call Base's toString(), since as far as it know's that's an instance of Base.