C++ 类:虚拟和重写,还是两者都不?

TCF*_*TCF 3 c++ virtual overriding class

实际上有必要使用or virtual override

\n\n

我知道关于这个一般性主题有很多问题,例如:

\n\n\n\n

从这些以及其他标记为重复项的内容中(许多“重复项”的答案包含了至少对我来说是新的独特信息),我学到了一些东西(并且我认为,大致了解它们的原因) re true): 没有 virtual 的覆盖将无法编译。没有覆盖的虚拟将编译,但如果您犯了一个错误并且方法签名不正确,编译器不会告诉您。

\n\n

但是如果我省略两者会发生什么?例子:

\n\n
struct BaseClass {\n    int a_number() {\n        return 1;\n    }\n};\nstruct DerivedClass : BaseClass {\n    int a_number() {\n        return 2;\n    }\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

这将编译并a_number返回适当的结果,无论我实例化BaseClass还是DerivedClass. 所以它的行为就好像我已经覆盖了该函数。上面的代码有错误吗?这是向后兼容性问题还是其他问题?

\n\n

如果我错过的相关问题之一直接回答了这个问题,我深表歉意,谢谢。

\n\n

编辑:StackOverflow 不断将我指向派生类中函数的 C++ \xe2\x80\x9cvirtual\xe2\x80\x9d 关键字。有必要吗?问题,正如威克在下面所做的那样。我不认为它解决了我的问题,因为我在评论中给了他/她,因为它们是暂时的,我将在这里重复:\n“我特别询问超类方法中的虚拟,虽然那篇文章似乎是关于子类中的 virtual 及其传播方式。下面接受的答案回答了我的问题,但我不认为你的链接可以回答(它可能会回答在 C/C++ 方面更有经验的人的问题,但我我不认为它能回答像我这样来自 Python 和 Java 的新手的问题)。”

\n\n

要点:我认为这些问题是相关的,但不一样。

\n\n

我接受了塞尔比的回答,因为这是回答我的问题的第一个成熟的“答案”。怀克的回答提供了很多有用的、更一般的信息。

\n

sel*_*bie 5

正如您所声明的那样(没有虚拟方法),如果BaseClass::a_number没有声明,则将其强制转换为 asvirtual的实例将不会调用中的实现DerivedClassBaseClassDerivedClass

例子:

BaseClass* instance1 = new DerivedClass();
instance1->a_number();  // returns "1", even though the object is really an instance of Derived
Run Code Online (Sandbox Code Playgroud)

如果 BaseClass 声明如下:

struct BaseClass {
    virtual int a_number() {
        return 1;
    }
};
Run Code Online (Sandbox Code Playgroud)

然后以下代码将按您的预期工作

BaseClass* instance2 = new DerivedClass();
instance2->a_number();  // returns "2", virtual method invocation
Run Code Online (Sandbox Code Playgroud)

override关键字是可选的,但建议在 DerivedClass 中使用:

struct DerivedClass : BaseClass {
    int a_number() override {
        return 2;
    }
};
Run Code Online (Sandbox Code Playgroud)

正如您已经观察到的,override不会改变程序行为,但如果a_number在 中没有进行相同的声明BaseClass,编译器将发出错误。它对于捕获拼写错误很有用。