C++ 所有的虚函数都需要在派生类中实现吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8931612/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:21:24  来源:igfitidea点击:

Do ALL virtual functions need to be implemented in derived classes?

c++inheritance

提问by mikestaub

This may seem like a simple question, but I can't find the answer anywhere else.

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

Suppose I have the following:

假设我有以下内容:

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

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

Is it ok that class Derived does not implement the bar() function? What if not ALL of my derived classes need the bar() function, but some do. Do all of the virtual functions of an abstract base class need to be implemented in the derived classes, or just the ones that are pure virtual? Thanks

Derived 类不实现 bar() 函数可以吗?如果不是我的所有派生类都需要 bar() 函数,但有些需要,该怎么办。抽象基类的所有虚函数都需要在派生类中实现,还是只需要在纯虚函数中实现?谢谢

采纳答案by Rob Kennedy

Derived classes do nothave to implement allvirtual functions themselves. They only need to implement the pureones.1That means the Derivedclass in the question is correct. It inheritsthe barimplementation from its ancestor class, Abstract. (This assumes that Abstract::baris implemented somewhere. The code in the question declares the method, but doesn't define it. You can define it inline as Trenki's answershows, or you can define it separately.)

派生类也没有必须实现所有的虚函数本身。他们只需要实现的。1这意味着问题中的Derived类是正确的。它从其祖先类继承bar实现,Abstract. (这假设在Abstract::bar某处实现了。问题中的代码声明了该方法,但没有定义它。您可以按照Trenki 的答案所示对其进行内联定义,也可以单独定义它。)



1And even then, only if the derived class is going to be instantiated. If a derived class is not instantiated directly, but only exists as a base class of more derived classes, then it's thoseclasses that are responsible for having all their pure virtual methods implemented. The "middle" class in the hierarchy is allowed to leave some pure virtual methods unimplemented, just like the base class. If the "middle" class doesimplement a pure virtual method, then its descendants will inherit that implementation, so they don't have to re-implement it themselves.

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

回答by trenki

Only the pure virtual methods have to be implemented in derived classes, but you still need a definition (and not just a declaration) of the other virtual methods. If you don't supply one, the linker might very well complain.

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

So, just putting {}after your optional virtual method gives you an empty default implementation:

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

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

A more involved default implementation would go into a separate source file though.

不过,更复杂的默认实现将进入单独的源文件。

回答by Alok Save

The ISO C++ Standard specifies that all virtual methods of a class that are not pure-virtual must be defined.

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

Simply put the rule is:
If your derived class overiddes the Base class virtual method then it should provide a definition as well, If not then the Base class should provide the definition of that method.

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

As per the above rule in your code example, virtual void bar();needs a definition in the Base class.

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

Reference:

参考:

C++03 Standard: 10.3 Virtual functions [class.virtual]

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

A virtual function declared in a class shall be defined, or declared pure (10.4) in that class, or both; but no diagnostic is required (3.2).

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

So either you should make the function pure virtual or provide a definition for it.

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

The gcc faqdoccuments it as well:

gcc的常见问题doccuments它还有:

The ISO C++ Standard specifies that all virtual methods of a class that are not pure-virtual must be defined, but does not require any diagnostic for violations of this rule [class.virtual]/8. Based on this assumption, GCC will only emit the implicitly defined constructors, the assignment operator, the destructor and the virtual table of a class in the translation unit that defines its first such non-inline method.

Therefore, if you fail to define this particular method, the linker may complain about the lack of definitions for apparently unrelated symbols. Unfortunately, in order to improve this error message, it might be necessary to change the linker, and this can't always be done.

The solution is to ensure that all virtual methods that are not pure are defined. Note that a destructor must be defined even if it is declared pure-virtual [class.dtor]/7.

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

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

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

回答by Jason

Yes, that's fine ... you only need to implement any pure virtual functions in order to instantiate a class derived from an abstract base class.

是的,这很好……您只需要实现任何纯虚函数即可实例化从抽象基类派生的类。

回答by CodeCodeCode

Yes, Its correct that a Derived class has to OVERRIDE the function which is Pure Virtual in the Parent Class. Parent class having a Pure Virtual Function is called Abstract Class only because it's Child class must give their own body of the Pure Virtual Function.

是的,派生类必须覆盖父类中的纯虚拟函数是正确的。具有纯虚函数的父类被称为抽象类只是因为它的子类必须提供自己的纯虚函数体。

For the Normal Virtual Functions:- Its not necessary to override them further, as some child class may have that function, some may not have.

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

Main purpose of Virtual Function mechanism is Run Time Polymorphism, whether main purpose of Pure Virtual Function(Abstract Class) is to make it mandatory to have the same name Function with own's body.

虚函数机制的主要目的是运行时多态性,纯虚函数(抽象类)的主要目的是强制要求与自己的函数体具有同名函数。