C ++虚拟继承内存布局

时间:2015-06-16 14:09:50

标签: c++ oop inheritance multiple-inheritance virtual-inheritance

虚拟继承内存布局

我试图通过虚拟继承和vTables / vPtrs来完全理解内存中发生的事情,而不是。

我有两个我编写的代码示例,我完全理解它们的工作原理,但我只是想确保在脑海中对对象内存布局有正确的想法。

Here是图片中的两个示例,我只想知道我对所涉及的内存布局的想法是否正确。

示例1:

class Top { public: int a;  };
class Left : public virtual Top {  public: int b; };
class Right : public virtual Top { public: int c; };
class Bottom : public Left, public Right { public:  int d; };

enter image description here

示例2:

与上述相同,但是:

class Right : public virtual Top {
public:
    int c;
    int a;  // <======= added this
};

enter image description here

1 个答案:

答案 0 :(得分:0)

C ++标准并没有对对象布局说太多。虚函数表(vtable)和虚拟基指针甚至不是标准的一部分。所以问题和asnwers只能说明可能的实现。

快速查看图形似乎显示正确的布局。

您可能会对这些进一步的参考感兴趣:

编辑:底部是继承Right::a还是Left::a

测试2 中,RightLeft共享相同的公共父Top。因此Top中只有一个子对象Bottom,因此只有一个Top::aa

有趣的是,您已在测试中介绍了Right中的成员a。这是a,与Top继承的a不同。它是一个独特的成员,只是与另一个成员同名,并且巧合#34;。因此,如果您通过Right访问Right::aTop::a会隐藏Bottom::Top::a(顺便提一下Right::Top::aLeft::Top::aint main() { Bottom bottom; bottom.a = 7; cout << bottom.Top::a << endl << bottom.Left::Top::a << endl; cout << bottom.Right::Top::a << endl << bottom.Left::a << endl; cout << bottom.Right::a << endl <<endl; bottom.Right::a = 4; bottom.Left::a = 3; cout << bottom.Top::a << endl << bottom.Left::Top::a << endl; cout << bottom.Right::Top::a << endl << bottom.Left::a << endl; cout << bottom.Right::a << endl <<endl; cout << "And the addresses are: " << endl; cout << " Bottom: " << (void*)&bottom << endl; cout << " Top: " << (void*)static_cast<Top*>(&bottom) << endl; cout << " Left: " << (void*)static_cast<Left*>(&bottom) << endl; cout << " Right: " << (void*)static_cast<Right*>(&bottom) << endl; cout << " Top::a: " << (void*)&bottom.Top::a << endl; cout << " Left::Top::a: " << (void*)&bottom.Left::Top::a << endl; cout << " Right::Top::a:" << (void*)&bottom.Right::Top::a << endl; cout << " Left::a: " << (void*)&bottom.Left::a << endl; cout << " Rigth::a: " << (void*)&bottom.Right::a << endl; }; )。在这种情况下,bottom.a表示Right :: a,不是因为对象布局,而是因为名称loockup(和隐藏)规则。这不依赖于实现:它是标准的和可移植的。

这是测试2的变体,用于演示这种情况:

{{1}}