C++有个菱形的虚继承,我看不管是MSVC还是GCC都是把最上面的基类,排在了内存的最高位,这是有什么好处吗?
就像这个继承图,如果定义了一个G对象,那么在内存中排序从低到高依次是 S1变量,S2变量 ,G变量,B变量
但是为什么不是基类B变量排最前面呢?
C++有个菱形的虚继承,我看不管是MSVC还是GCC都是把最上面的基类,排在了内存的最高位,这是有什么好处吗?
就像这个继承图,如果定义了一个G对象,那么在内存中排序从低到高依次是 S1变量,S2变量 ,G变量,B变量
但是为什么不是基类B变量排最前面呢?
因为虚基类不管继承多少次,在派生对象中只能有一个子对象。如果把它放到前面的话,多继承时就会出现多个虚基类子对象。因此虚基类子对象是放在所有子对象之后的。
https://en.cppreference.com/w/cpp/language/derived_class
For each distinct base class that is specified virtual, the most derived object contains only one base class subobject of that type, even if the class appears many times in the inheritance hierarchy (as long as it is inherited virtual every time).
https://stackoverflow.com/questions/6258559/what-is-the-vtt-for-a-class
// The Diamond: Single Copies of Virtual Bases
class A {
public:
int a;
virtual void v();
};
class B : public virtual A {
public:
int b;
virtual void w();
};
class C : public virtual A {
public:
int c;
virtual void x();
};
class D : public B, public C {
public:
int d;
virtual void y();
};
+-----------------------+
| 20 (vbase_offset) |
+-----------------------+
| 0 (top_offset) |
+-----------------------+
| ptr to typeinfo for D |
+----------> +-----------------------+
d --> +----------+ | | B::w() |
| vtable |----+ +-----------------------+
+----------+ | D::y() |
| b | +-----------------------+
+----------+ | 12 (vbase_offset) |
| vtable |---------+ +-----------------------+
+----------+ | | -8 (top_offset) |
| c | | +-----------------------+
+----------+ | | ptr to typeinfo for D |
| d | +-----> +-----------------------+
+----------+ | C::x() |
| vtable |----+ +-----------------------+
+----------+ | | 0 (vbase_offset) |
| a | | +-----------------------+
+----------+ | | -20 (top_offset) |
| +-----------------------+
| | ptr to typeinfo for D |
+----------> +-----------------------+
| A::v() |
+-----------------------+