虚拟继承内存布局
我试图完全理解虚拟继承和 vTables/vPtrs 的内存幕后发生的事情以及不发生的事情。
我有两个我编写的代码示例,我确切地理解它们工作的原因,但我只是想确保我心中对对象内存布局有正确的想法。
Here http://postimg.org/image/eyhxhc7g1/full/是图片中的两个示例,我只是想知道我对所涉及的内存布局的想法是否正确。
示例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; };
示例2:
与上面相同,但具有:
class Right : public virtual Top {
public:
int c;
int a; // <======= added this
};
C++ 标准没有对对象布局做太多说明。虚拟函数表(vtable)和虚拟基指针甚至不是标准的一部分。所以问题和答案只能说明可能的实现。
快速查看您的绘图似乎显示了正确的布局。
您可能对这些进一步的参考资料感兴趣:
-
多重继承被认为是有用的 http://www.drdobbs.com/cpp/multiple-inheritance-considered-useful/184402074一篇关于多重继承和虚拟继承情况下的布局的 ddj 文章。
-
微软专利 http://www.google.com.pa/patents/US5754862描述 vfptr(虚拟函数表,又名 vtable)和 vbptr(虚拟基指针)的使用。
编辑:Bottom 是否继承Right::a
or Left::a
?
In your test 2, Right
and Left
拥有同一个共同的父母Top
。所以只有一个子对象Top
within Bottom
,因此,只有一个且相同的Top::a
.
有趣的是,您在测试 2 中引入了一名成员a
in Right
。这是一a
这与a
继承自Top
。它是一个独特的成员,只是“巧合”地与另一个成员同名。所以如果你访问a
通过Right
, Right::a
隐藏Top::a
(顺便说一下,这也是Bottom::Top::a
, the Right::Top::a
, the Left::Top::a
)。在本例中,bottom.a 表示 Right::a,不是因为对象布局,而是因为名称查找(和隐藏)规则。这与实现无关:它是标准的且可移植的。
这里有一个测试 2 的变体来演示这种情况:
int 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;
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)