gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 20:41:39 29 4
gpt4 key购买 nike

假设我在 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/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com