K.R*_*ark 4 c++ polymorphism pointers casting language-lawyer
在学习《Effective C++》时,我首先感到惊讶的是,如果一个类具有多重继承,那么当指针转换完成时,它的指针可能会发生偏移。虽然这不是一个容易掌握的概念,但我想我已经掌握了。
然而,作者声称即使在单继承类的指针转换中也可能发生这种偏移。我想知道这种情况是什么,并希望知道其背后的原理。
当派生类将多态性引入类层次结构时,就会发生这种情况。考虑下面的类:
struct Foo
{
int a;
int b;
};
Run Code Online (Sandbox Code Playgroud)
该类不是多态的,因此实现不需要包含指向虚拟调度表(实现虚拟调度的常用方法)的指针。它将在内存中这样布局:
Foo
+---+
a | |
+---+
b | |
+---+
Run Code Online (Sandbox Code Playgroud)
现在考虑一个继承自 的类Foo:
struct Bar : Foo
{
virtual ~Bar() = default;
};
Run Code Online (Sandbox Code Playgroud)
此类是多态的,因此此类的对象需要包含指向 vtable 的指针,以便进一步的派生类可以重写 的Bar虚拟成员函数。这意味着Bar对象将像这样在内存中布局:
Bar
+---------+
vtable pointer | |
+---------+
Foo subobject | +---+ |
| a | | |
| +---+ |
| b | | |
| +---+ |
+---------+
Run Code Online (Sandbox Code Playgroud)
由于对象的Foo子对象不在对象的开头,因此Foo*从指向Bar对象的指针初始化的任何内容都需要调整指针的大小,以便它实际上指向Bar对象的Foo子对象。