在C++中,如果一个函数覆盖虚函数,它是否会自动虚拟化?

Jul*_*ian 21 c++ virtual overriding

我希望如果foo在类中声明D,但没有标记为虚拟,那么下面的代码将调用fooin 的实现D(无论动态类型如何d).

D& d = ...;
d.foo();
Run Code Online (Sandbox Code Playgroud)

但是,在以下程序中,情况并非如此.有谁能解释一下?如果方法覆盖虚函数,它是否会自动虚拟化?

#include <iostream>

using namespace std;

class C {
public:
        virtual void foo() { cout << "C" << endl; }
};

class D : public C {
public:
        void foo() { cout << "D" << endl; }
};

class E : public D {
public:
        void foo() { cout << "E" << endl; }
};

int main(int argc, char **argv)
{
        E& e = *new E;
        D& d = *static_cast<D*>(&e);
        d.foo();
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

上述程序的输出是:

E
Run Code Online (Sandbox Code Playgroud)

Tad*_*pec 22

标准10.3.2(class.virtual)说:

如果虚拟成员函数vf在类Base和Derived类中声明,直接或间接从Base派生,则声明具有与Base :: vf相同名称和相同参数列表的成员函数vf,然后Derived :: vf也是虚拟的(无论是否如此声明)并覆盖*

[脚注:具有相同名称但作为虚函数的不同参数列表(子句)的函数不一定是虚拟的,也不会覆盖.在覆盖函数的声明中使用虚拟说明符是合法的但是冗余的(具有空语义).在确定覆盖时不考虑访问控制(子句class.access).---结束foonote]


not*_*row 17

快速回答可能不是,但正确答案是肯定的

C++不知道函数隐藏,所以覆盖虚函数,没有虚拟关键字标记,也是虚函数.

  • @Yossarian,这就是为什么将派生类中的虚函数声明为虚拟的良好做法,以便明确意图.Scott Meyers在他的Effective C++书中对此进行了讨论. (11认同)
  • @ v.oddou"我听说过某个地方"人们"在某个地方听到的"通​​常都是假的.;-)只要在层次结构中有一个标记为`virtual` _somewhere_的相同签名的函数,那么具有相同签名的任何派生函数都是覆盖.声明中包含"虚拟"的声明是否"无关紧要",同样,关键字在其最基本的外观之后具有空语义. (2认同)