子类型的对象在c++中使用哪个vtable
Which vtable does the object of subtype use in c++
当我想执行这行代码时,它不会编译
baseArray[1]->function5();
但在导数3的vtable中,函数5应该指向导数1中的函数5。所以我认为它应该输出Derived1::function5((。但它似乎在基类中找到了function5((
我只是想知道Derived3继承了Derived1,为什么它仍然检查基类中是否存在被调用的函数?
请参考以下代码。谢谢你的帮助!
#include <iostream>
using namespace std;
class Base {
public:
virtual void function1();
virtual void function2();
virtual void function3() = 0;
void function4();
};
class Derived1 : public Base {
public:
void function1();
virtual void function5();
void function6();
};
class Derived2 : public Base {
public:
void function2();
void function3();
void function4();
void function5();
};
class Derived3 : public Derived1 {
public:
void function3();
};
void Base::function1(){
cout << "Base::function1()" << endl;
}
void Base::function2(){
cout << "Base::function2()" << endl;
}
void Base::function4(){
cout << "Base::function4()" << endl;
}
void Derived1::function1(){
cout << "Derived1::function1()" << endl;
}
void Derived1::function5(){
cout << "Derived1::function5()" << endl;
}
void Derived1::function6(){
cout << "Derived1::function6()" << endl;
}
void Derived2::function2(){
cout << "Derived2::function2()" << endl;
}
void Derived2::function3(){
cout << "Derived2::function3()" << endl;
}
void Derived2::function4(){
cout << "Derived2::function4()" << endl;
}
void Derived2::function5(){
cout << "Derived2::function5()" << endl;
}
void Derived3::function3(){
cout << "Derived3::function3()" << endl;
}
int main(){
Base *baseArray[] = { new Derived2, new Derived3 };
baseArray[1]->function5(); //why the code doesn't compile when I call function5() here?
//in vtable of Derived 3, function5 should points to function5 in Derived1
//so I think it should output Derived1::function5()
dynamic_cast<Derived3*>(baseArray[1])->function5();
baseArray[1]->function6(); //same question, why it doesn't call function6 in Derived1?
//which vtable does baseArray[1] use?
dynamic_cast<Derived3*>(baseArray[1])->function6();
}
C++是一种静态类型的语言。这意味着对类型、成员、变量等的引用必须在编译时已知。
baseArray[1]->function5();
和baseArray[1]->function6();
不编译的原因是baseArray[1]
被声明为Base*
,但function5()
和function6()
不是Base
的成员。就这么简单。这与vtables无关。这只是编译器如何选择在运行时实现虚拟方法调用调度的实现细节,但这不是C++标准所要求的。
编译器不知道Base*
指针实际指向的是Derived3
对象。这个事实要到运行时才能确定。这是多态性的一个关键特征。
要正确调用function5()
和function6()
,您需要将Base*
指针类型转换为具有您想要访问的成员的派生类型,正如您已经发现的那样。请注意,如果强制转换失败,指针上的dynamic_cast
将返回nullptr
,而您没有检查,例如:
// Derived1 and Derived2 are not related, but each has its own function5()...
if (Derived1 *d1 = dynamic_cast<Derived1*>(baseArray[index]))
d1->function5();
else if (Derived2 *d2 = dynamic_cast<Derived2*>(baseArray[index]))
d2->function5();
另一方面,如果您预先知道准确和正确的类型(如您的示例(,则可以使用static_cast
,例如:
static_cast<Derived1*>(baseArray[index])->function5();
相关文章:
- 纯虚拟类和错误未定义对 'vtable 的引用
- 对植物的 vtable 的未定义引用?
- 如何查看在程序级别为我的程序创建了多少 vtable 和 vpointer
- 未定义的符号缺少 vtable
- 编译器是否会创建vtable,而不考虑在c++中创建对象
- 为什么重复的空基存储不与 vtable 指针重叠?
- 如何在生产中避免vtable查找,并且仍然能够在单元测试中进行广泛的模拟
- 在C中实现vtable而不是使用C++的目的
- 如果使用非公共类,vtable 是否会在二进制文件中持续存在?
- 关于这个在 Linux 上使用 gcc 编译的程序中的 vtable,nm 告诉我什么?
- 使用多个命名空间对 vtable 的未定义引用
- D3D9创建设备,在Alt选项卡后获得vtable黑屏
- 避免对仅在源文件中定义的类发出弱 vtable 警告
- 在C++中声明"interface",而不是将其 vtable 发送到每个翻译单元
- 虚拟继承情况下的 vtable
- 对"车辆的 vtable"的未定义引用 - 面向对象的编程练习
- 为什么虚拟继承即使不涉及虚拟功能也需要 vtable?
- 为什么 fdump-class-hierarchy 为虚函数提供了两个指针 int vtable
- ASAN 检测与动态加载库共享的类的 vtable 的 ODR 违规
- Qt Quick + CMake + 自定义 QObject 导致对"vtable"的未定义引用