c++ - 为什么虚拟关键字 "persistent"贯穿 C++ 的整个层次结构?

标签 c++ inheritance

假设我在 3 个类 A、B 和 C 中有一个函数 print()。 C继承自B继承自A。 关键字 virtual 仅在 A 中使用。

为什么下面两个都使用C中的print()?

    A* ac = new C();
    ac->print(); //C's print() 

    B* bc = new C();
    bc->print(); //C's print(), not B's print() even though virtual is not used.

这里的直觉是什么?

如果你想编译/运行它,下面是完整的工作代码:

#include <iostream>
#include <cstdlib>

using namespace std;

class A{
public:
    A(){
        cout << "construct A" << endl;
    }
    virtual void print(){
        cout << "A says" << endl;
    }
};


class B: public A{
public:    
    B(){
        cout << "construct B" << endl;
    }
    void print(){
        cout << "B says" << endl;
    }    
};

class C: public B{
public:    
    C(){
        cout << "construct C" << endl;
    }
    void print(){
        cout << "C says" << endl;
    }    
    void print(int x){
        cout << "C says " << x << endl;
    }
};


int main(){

    A* ac = new C();
    ac->print();

    B* bc = new C();
    bc->print();

    return 0;
}

最佳答案

因为这就是 C++ 的工作方式——一旦具有特定签名的函数被标记为 virtual,它在每个派生类中仍然是 virtual,无论它们是否显式使用关键字与否。我的偏好是始终使用额外的(冗余的)virtual 来清楚地说明发生了什么,但其他人认为不需要它,所以您不妨将其省略。

(但是,具有不同签名的重载不会自动成为虚拟的,事实上会隐藏同名的基类方法,除非 using 指令用于将基类定义带入派生范围。)

至于推理,我认为没有任何特定的语言理由可以禁止您“去虚拟化”一个函数。我想 Stroustrup 在早期就决定宽容人们在派生类中忘记 virtual,并因此出现意外行为。

关于c++ - 为什么虚拟关键字 "persistent"贯穿 C++ 的整个层次结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20557692/

相关文章:

c++ - LISP 解析器 C++

c++ - 模板内的继承 - 公共(public)成员变得不可见?

c++ - 类 Square 应该从类 Rectangle 公开继承吗?

C++ : Accessing private member of base or global variable from a derived class

Java继承错误

c++ - 接口(interface)的自动代理类

c++ - 如果我在构造函数中写return语句怎么办?

c++ - 根据模板类型启用模板类中的方法

c++ - 如何让 C++ 从 USB 端口(如串行端口)执行 I/O

c++ - 当重新分配或作为ROI时,源Mat被释放时,Mat指针是否会自动释放?