gpt4 book ai didi

c++ - 与 C++ 中的 virtual 关键字混淆

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:57:27 24 4
gpt4 key购买 nike

我正在研究 C++ 中 virtual 关键字的效果,我想出了这段代码。

#include<iostream>

using namespace std;

class A {
public:
virtual void show(){
cout << "A \n";
}
};

class B : public A {
public:
void show(){
cout << "B \n";
}
};

class C : public B {
public:
void show(){
cout << "C \n";
}
};

int main(){

A *ab = new B;
A *ac = new C;
B *bc = new C;
ab->show();
ac->show();
bc->show();

}

预期的输出是:

B
C
B

因为 B 中的 show 函数是非虚拟的。但是编译时的结果是:

B
C
C

它的行为就好像 B 中的 show 函数是虚拟的。为什么会这样? B类在这里被覆盖了吗?如果我将 C 类指向 B 类,我怎么会指向 A 类?

最佳答案

根据 C++ 2017 标准(10.1.2 函数说明符)

2 The virtual specifier shall be used only in the initial declaration of a non-static class member function; see 13.3.

和(13.3虚函数)

2 If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list (11.3.5), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides111 Base::vf. For convenience we say that any virtual function overrides itself. A virtual member function C::vf of a class object S is a final overrider unless the most derived class (4.5) of which S is a base class subobject (if any) declares or inherits another member function that overrides vf. In a derived class, if a virtual member function of a base class subobject has more than one final overrider the program is ill-formed.

因此类 B 中的函数 show 是一个虚函数,因为它与类 A 中声明的函数具有相同的签名.

考虑一个更有趣的示例,在类 B 中,向成员函数 show 添加了限定符 const

#include<iostream>

using namespace std;

class A {
public:
virtual void show(){
cout << "A \n";
}
};

class B : public A {
public:
void show() const{
cout << "B \n";
}
};

class C : public B {
public:
void show() {
cout << "C \n";
}
};

int main(){

A *ab = new B;
A *ac = new C;
B *bc = new C;
ab->show();
ac->show();
bc->show();

}

在这种情况下,输出看起来像

A 
C
B

在这个表达式语句中

    ab->show();

A中声明了虚函数show

在这个声明中

    ac->show();

在类 C 中调用了被覆盖的相同虚函数。编译器在类A中使用了虚函数声明,因为指针ac的静态类型是A *

在这个声明中

    bc->show();

调用非虚拟成员函数show,限定符const 因为指针bc 的静态类型是B * 并且编译器在类 B 中找到隐藏类 A 中声明的虚函数的函数..

对于原始程序,您可以使用说明符 override 使类定义更加清晰。例如

#include<iostream>

using namespace std;

class A {
public:
virtual void show(){
cout << "A \n";
}
};

class B : public A {
public:
void show() override{
cout << "B \n";
}
};

class C : public B {
public:
void show() override{
cout << "C \n";
}
};

int main(){

A *ab = new B;
A *ac = new C;
B *bc = new C;
ab->show();
ac->show();
bc->show();

}

关于c++ - 与 C++ 中的 virtual 关键字混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47201589/

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