是否所有的虚函数都需要在派生类中实现?
这可能看起来像一个简单的问题,但我无法在其他地方find答案。
假设我有以下几点:
class Abstract { public: virtual void foo() = 0; virtual void bar(); } class Derived : Abstract { public: virtual void foo(); }
Derived类不能实现bar()函数吗? 如果不是我所有的派生类都需要bar()函数,但是有一些呢。 所有的抽象基类的虚函数都需要在派生类中实现,还是仅仅是纯虚拟的? 谢谢
派生类不必自己实现所有的虚函数。 他们只需要实现纯粹的。 1这意味着问题中的Derived
类是正确的。 它inheritance了其祖先类Abstract
。 (这里假定Abstract::bar
是在某个地方实现的,问题中的代码声明了方法,但没有定义它,你可以像Trenki的答案显示的那样在内联中定义它,也可以单独定义。
1即使如此,只有派生类将被实例化 。 如果一个派生类没有直接实例化,而只是作为更多派生类的基类存在,那么这些类就是负责实现所有纯虚函数的类。 允许层次结构中的“中间”类实现一些纯粹的虚拟方法,就像基类一样。 如果“中间”类实现了一个纯粹的虚拟方法,那么它的后代将inheritance这个实现,所以它们不必自己重新实现它。
只有纯粹的虚拟方法必须在派生类中实现,但是您仍然需要其他虚拟方法的定义(而不仅仅是声明)。 如果你不提供一个,链接器可能会抱怨。
所以,只要在可选的虚拟方法之后放置一个空的默认实现:
class Abstract { public: virtual void foo() = 0; // pure virtual must be overridden virtual void bar() {} // virtual with empty default implementation }; class Derived : Abstract { public: virtual void foo(); };
更多涉及的默认实现将会进入一个单独的源文件。
ISO C ++标准规定必须定义非纯虚拟类的所有虚拟方法。
简单的说就是:
如果派生类覆盖了Base类的虚方法,那么它也应该提供一个定义。如果不是,那么Base类应该提供该方法的定义。
根据代码示例中的上述规则, virtual void bar();
需要在Base类中定义。
参考:
C ++ 03标准:10.3虚函数[class.virtual]
在一个类中声明的虚拟函数应该在这个类中定义或者声明为纯的(10.4) 但不需要诊断(3.2)。
所以要么你应该使这个函数是纯虚拟的或者为它提供一个定义。
海湾合作委员会常见问题解释它:
ISO C ++标准规定,一个非纯虚拟的类的所有虚拟方法必须被定义,但是不需要任何诊断来违反这个规则
[class.virtual]/8
。 基于这个假设,GCC将只在定义其第一个这样的非内联方法的翻译单元中发出隐式定义的构造函数,赋值运算符,析构函数和类的虚表。因此,如果你没有定义这个特定的方法,那么链接器可能会抱怨缺乏对不相关的符号的定义。 不幸的是,为了改善这个错误信息,可能有必要改变链接器,这并不总是可以完成的。
解决scheme是确保所有不纯的虚拟方法都被定义。 请注意,即使声明为纯虚拟的
[class.dtor]/7
,也必须定义析构函数。
是的,没关系……你只需要实现任何纯虚函数就可以实例化一个派生自抽象基类的类。
是的,派生类必须覆盖父类中的纯虚函数才是正确的。 具有纯虚函数的父类仅被称为抽象类,因为它的子类必须给出它们自己的纯虚函数体。
对于普通虚拟函数: – 没有必要进一步覆盖它们,因为一些子类可能有这个function,有些可能没有。
虚函数机制的主要目的是运行时多态,纯虚函数(Abstract Class)的主要目的是使它与自己的身体具有相同的名称Function。