classA : public VirtualClass { public: int number; A(int n):number(n),VirtualClass(n+2){ cout<<"Create A"<<endl; }
~A() { cout << "Destroy A" << endl; } };
classB : public VirtualClass { public: int number; B(int n):number(n), VirtualClass(n + 1) {cout<<"Create B"<<endl;}
virtual ~B() { cout << "Destroy B" << endl; } };
classC : public A,public B { public: C(int n):A(n*n),B(n){cout<<"Create C"<<endl;}
virtual ~C() { cout << "Destroy C" << endl; } };
intmain() { C* c = newC(4);
//cout << "number in B = " << c->number << endl; Error 错误: C::number不明确 cout << "number in A = " << c->A::number << endl; cout << "number in B = " << c->B::number << endl; cout << "number in (A)BaseClass = " << c->A::vInt << endl; cout << "number in (B)BaseClass = " << c->B::vInt << endl; delete c; return0; }
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Create VirtualClass Create A Create VirtualClass Create B Create C number in A = 16 number in B = 4 number in (A)BaseClass = 18 number in (B)BaseClass = 5 Destroy C Destroy B Delete VirtualClass Destroy A Delete VirtualClass
classC : public A,public B { public: C(int n):A(n*n),B(n),VirtualClass(n*n+n+2){cout<<"Create C"<<endl;} //添加VirtualClass的构造函数
virtual ~C() { cout << "Destroy C" << endl; } };
使用虚继承后,C的内部结构发生了变化。子类对象中包含了A、B、VirtualClass的对象数据,A、B两个类中创建了vbptr指针(virtual base table pointer),该指针指向一个虚表,表中记录了(1)vbptr与本类的偏移地址(2)vbptr与共有基类成员的偏移地址。在示例中B的VirtualClassptr指向C中的虚表,虚表记录了公共基类的成员变量vInt与类B初始位置的内存偏移。通过该偏移就能找到基类的成员,从而避免了数据的冗余,解决了不一致性。