类继承和虚拟函数表
Class inheritance and the virtual function table
一个简单的层次结构:
class X
{
public:
virtual void test(){ printf("xn");}
};
class Y : public X
{
public:
virtual void test() { printf("yn");}
};
class Z : public Y
{
public:
void test() { printf("zn");}
};
如果我创建z的一个实例,我希望这个实例的vtable会指向z的测试函数,无论我将它投射到哪个基:
Z myZ;
myZ.test();
((Y)myZ).test();
我在这里错过了什么?
这是因为您对myZ
进行了实际的类型转换。通过这样做,编译器将创建一个类型为Y
的临时对象(Y)myZ
,并使用它来调用它的test
方法。
你的代码的一个更长的等价物是这样的:
Z myZ;
Y tmp = Y(myZ);
tmp.test();
您可以看到,如果test
方法以任何方式修改对象,就会发生这种情况。则((Y)myZ).test()
不应修改myZ
。
正如所指出的,动态调度只需要发生在指针或引用上。
事实上,你无法区分有指针和无指针,例如,你可以在X
中使用类似的蹦床方法,尽管你使用了指针,它仍然会调用Y::test
:
class X {
public:
void call_test() {
this->test();
}
}
动态调度不发生的事实可以被视为一种优化技术。编译器知道((Y)myZ)
将具有Y
的虚拟表,因此可以立即调用Y::test
。
((Y)myZ)
由于CCD_ 13不是指针。因此,将调用Y::test
,因为这里没有关于Z
的信息。
但您可以使用指针(或引用(:
Z* z = new Z();
z->test();
Y* y = z;
y->test();
delete z;
z
将打印两次。
相关文章:
- C++无法定义虚拟函数 OUTER 类和头文件
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- 当覆盖存在时调用基本虚拟"binded to object"函数
- 如何在C++中伪造虚拟可变参数函数模板?
- 类型擦除的std::function与虚拟函数调用的开销
- 重写虚拟函数和继承
- 是否可以使用函数指针调用虚拟析构函数?
- 在没有动态内存的世界中,我是否需要虚拟析构函数?
- 虚拟继承基构造函数消除
- "虚拟""覆盖"析构函数
- 类中的虚拟布尔函数参数不起作用
- 用纯虚拟函数兜圈子
- 将C++子类成员函数(虚拟实现)传递给 C 类型函数指针
- 尝试在 QLabel 上绘画失败(无法在没有对象的情况下调用成员函数"虚拟无效 QLabel::p aintEvent(QPaintEvent*)")
- 声明析构函数虚拟就足够了吗?
- 视觉 C++当我们在基类中使函数成为纯虚拟时,那么在子类中再次使相同的函数虚拟的必要性是什么
- 重载函数(虚拟/非虚拟)