是否需要在派生类中实现所有虚函数?

时间:2012-01-19 18:51:12

标签: c++ inheritance

这似乎是一个简单的问题,但我无法在其他任何地方找到答案。

假设我有以下内容:

class Abstract {
public:
    virtual void foo() = 0;
    virtual void bar();
}

class Derived : Abstract {
public:
    virtual void foo();
}

类Derived是否可以实现bar()函数? 如果不是我的所有派生类都需要bar()函数,但有些人会这样做。 是否需要在派生类中实现抽象基类的所有虚函数,还是只需要纯虚拟的? 感谢

5 个答案:

答案 0 :(得分:71)

派生类必须自己实现所有虚拟功能。他们只需要实现 pure 1 这意味着问题中的Derived类是正确的。 从其祖先类bar继承 Abstract实现。 (这假设Abstract::bar在某处实现。问题中的代码声明了方法,但没有定义它。您可以将其内联定义为Trenki's answer节目,或者您可以单独定义它。)


1 即便如此,只有派生类将被实例化。如果派生类没有直接实例化,而只是作为更多派生类的基类存在,那么那些负责实现所有纯虚方法的类。允许层次结构中的“中间”类保留一些未实现的纯虚方法,就像基类一样。如果“中间”类 实现纯虚方法,那么它的后代将继承该实现,因此它们不必自己重新实现它。

答案 1 :(得分:41)

只有纯虚方法必须在派生类中实现,但您仍需要其他虚方法的定义(而不仅仅是声明)。如果您不提供,链接器可能会抱怨。

因此,只需将{}放在可选的虚拟方法之后,就会为您提供一个空的默认实现:

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();
};

更复杂的默认实现会进入单独的源文件。

答案 2 :(得分:7)

ISO C ++标准规定必须定义非纯虚拟类的所有虚方法。

简单地说,规则是:
如果派生类覆盖了基类虚方法,那么它也应该提供定义,如果不是,那么Base类应该提供该方法的定义。

根据代码示例中的上述规则,virtual void bar();需要Base类中的定义。

参考:

C ++ 03标准:10.3虚函数[class.virtual]

  

在类中声明的虚函数应在该类中定义或声明为纯(10.4),或两者兼有;但不需要诊断(3.2)。

因此,您应该将该函数设为纯虚拟或为其提供定义。

gcc faq 也会对其进行处理:

  

ISO C ++标准规定必须定义非纯虚拟类的所有虚拟方法,但不要求违反此规则[class.virtual]/8的任何诊断。基于这个假设,GCC将仅在翻译单元中发出隐式定义的构造函数,赋值运算符,析构函数和类的虚拟表,以定义其第一个非内联方法。

     

因此,如果您未能定义此特定方法,链接器可能会抱怨缺少明显不相关的符号的定义。不幸的是,为了改进此错误消息,可能需要更改链接器,并且不能总是这样做。

     

解决方案是确保定义所有非纯的虚拟方法。请注意,即使将析构函数声明为纯虚拟[class.dtor]/7,也必须定义析构函数。

答案 3 :(得分:3)

是的,没关系......你只需要实现任何纯虚函数,以实例化从抽象基类派生的类。

答案 4 :(得分:0)

是的,Derived类必须覆盖父类中Pure Virtual的功能。具有纯虚函数的父类只被称为抽象类,因为它的Child类必须给它们自己的纯虚函数体。

对于普通虚拟功能: - 没有必要进一步覆盖它们,因为一些子类可能具有该功能,有些可能没有。

虚函数机制的主要目的是运行时多态性,纯虚函数(抽象类)的主要目的是使其必须与自己的身体具有相同的名称功能。