C++ 在C+中查找内存中某类对象布局的算法+;
考虑以下代码:C++ 在C+中查找内存中某类对象布局的算法+;,c++,inheritance,multiple-inheritance,C++,Inheritance,Multiple Inheritance,考虑以下代码: class A { public: virtual ~A(); virtual void foo(); }; class B : public A { public: virtual ~B(); virtual void foo(); }; 内存中B类对象的布局如下所示: 当我们谈到多重继承时,在内存中布局某个类的对象变得很困难,特别是当我们谈到菱形继承时,或者当我们谈到虚拟类时,如: class E : public C, public vi
class A {
public:
virtual ~A();
virtual void foo();
};
class B : public A {
public:
virtual ~B();
virtual void foo();
};
内存中B类对象的布局如下所示:
当我们谈到多重继承时,在内存中布局某个类的对象变得很困难,特别是当我们谈到菱形继承时,或者当我们谈到虚拟类时,如:
class E : public C, public virtual D, public virtual B {
public :
E() {
cout << "E::E()" << endl;
}
E(int x) : D(x) {
cout << "E::E(int)" << endl;
}
};
E类:公共C、公共虚拟D、公共虚拟B{
公众:
E(){
cout布局取决于编译器所针对的ABI。您应该研究ABI的文档,以了解类在内存中的布局方式
例如,使用.
< P>我假定你所给的图表认为C++是带有额外的C,并且从那个角度对实现定义的行为做出了假设。
它从左到右读取基说明符列表,深度优先,并假设虚拟继承是单个指针。每个带标签的框对应于类的非静态数据成员子对象(其中没有)。未标记的框是指向虚拟基的指针
我们从E
开始。它有一个非虚拟C
库,一个虚拟B
库和一个虚拟D
库。
C
有一个虚拟的B
子对象,它成为指针。
虚拟B
已经有一个指针,它将指向与C
的底部相同的位置。
虚拟D
需要一个指针
这结束了E
的非虚拟基,但仍有一些虚拟基尚未存储
我们制作了aB
,其中有一个非虚拟的a
,并在E
中记录偏移量。
我们制作了一个D
,它有一个非虚拟的B
,它有一个非虚拟的a
,并在E
中记录偏移量,除了标准布局类型外,它是实现定义的,可能也未指定:
对于多重继承模式,您可以使用static_cast来收集它的布局方式——尽管当时还没有gaurentee:如下所示:
void* offsetToB = static_cast<B*>(static_cast<A*>(nullptr));
void*offsetToB=static_cast(static_cast(nullptr));
免责声明:这不安全。没有固定或“标准”布局。它取决于ABI和编译器。请注意,虚拟表已经是一个实现细节。它是一个突出的细节,因为(几乎?)每一个实现都使用它,尽管C++标准不关心虚拟表,也没有什么可以依赖于该图看起来误导我。这些空白意味着<代码> E<代码>对象不连续地注意到,没有任何可移植的知识,你可以用这样一个怪物的布局来做。听起来像YO。有一位老师,你正在教C++misconceptions@vesii不会改变任何关于答案的东西。每个ABI都有自己的C++类布局规则(=算法)。