4.8虚基类问题的提出和初探

tech2022-10-28  113

虚基类(虚继承/虚派生)问题的提出

传统多重继承造成的 :空间问题,效率问题,二义性问题

#include <iostream> #include <vector> using namespace std; class Grand //爷爷类 { public: int m_grand; }; class A1 : public Grand { public: }; class A2 : public Grand { public: }; class C1 :public A1, public A2 { public: }; int main() { //一:虚基类(虚继承/虚派生)问题的提出 //传统多重继承造成的 :空间问题,效率问题,二义性问题; cout << sizeof(Grand) << endl; cout << sizeof(A1) << endl; cout << sizeof(A2) << endl; cout << sizeof(C1) << endl; /* 4 4 4 8 */ C1 c1; //c1.m_grand = 12; //访问不明确,名字冲突,二义性; //引入虚基类之后,就不会出现访问不明确的问题了 c1.A1::m_grand = 13; c1.A2::m_grand = 15; return 1; }

子类对象c1的空间布局(8字节)

虚基类

虚基类,让Grand类只被继承一次; 两个概念:(1)虚基类表 vbtable(virtual base table).(2)虚基类表指针 vbptr(virtual base table pointer)

virtual虚继承之后,A1,A2里就会被编译器插入一个虚基类表指针,这个指针,有点成员变量的感觉 A1,A2里因为有了虚基类表指针,因此占用了8个字节

#include <iostream> #include <vector> using namespace std; class Grand //爷爷类 { public: int m_grand; }; class A1 : virtual public Grand { public: }; class A2 : virtual public Grand { public: }; class C1 :public A1, public A2 { public: }; int main() { cout << sizeof(Grand) << endl; cout << sizeof(A1) << endl; cout << sizeof(A2) << endl; cout << sizeof(C1) << endl; /* 4 16 16 24 */ C1 c1; c1.m_grand = 12; //访问明确 c1.A1::m_grand = 13; c1.A2::m_grand = 15; return 1; }

子类24对象字节,左到右:前2个8字节是2个虚基类指针, m_grand,补齐

例子2

#include <iostream> #include <vector> using namespace std; class Grand //爷爷类 { public: int m_grand; }; class A1 : virtual public Grand { public: int m_a1; }; class A2 : virtual public Grand { public: int m_a2; }; class C1 :public A1, public A2 { public: int m_c1; }; int main() { cout << sizeof(Grand) << endl; cout << sizeof(A1) << endl; cout << sizeof(A2) << endl; cout << sizeof(C1) << endl; /* 4 24 24 48 */ A1 a1; a1.m_a1 = 9; a1.m_grand = 8; return 1; }

A1对象空间布局:虚基类指针,m_a1,补齐,m_grand A1父类成员m_grand放在了最后面

#include <iostream> #include <vector> using namespace std; class Grand //爷爷类 { public: int m_grand; }; class A1 : virtual public Grand { public: int m_a1; }; class A2 : virtual public Grand { public: int m_a2; }; class C1 :public A1, public A2 { public: int m_c1; }; int main() { cout << sizeof(Grand) << endl; cout << sizeof(A1) << endl; cout << sizeof(A2) << endl; cout << sizeof(C1) << endl; /* 4 24 24 48 */ C1 c1; c1.m_a1 = 9; c1.m_a2 = 7; c1.m_c1 = 6; c1.m_grand = 8; return 1; }

类C1对象布局(m_grand放在了最后面),其中两个8字节长的是虚基类指针

最新回复(0)