由于多重继承产生的二义性引入了类的虚继承,先看下什么是二义性。
类D是类B和类C的派生类,而类B,类C就是继承于类A,当D调用类A中的函数时不知道是类B继承A的,还是类C继承A的,引起了二义性。虚继承可以解决这个问题。
使用语法:
1 2 3
| class 派生类:virtual 继承方式 虚基类 { };
|
上图中类D 实例化过程中的初始化顺序:
祖父类(A)—>父类(从左到又)—>子类,并且最后一次初始化有效
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| #include <iostream> #include <string> using namespace std; class A { public: A(int a):i(a) { cout << "construct A" << endl; } void displaya() { cout << "A:" << i << endl; } private: int i; }; class B:virtual public A //虚继承 { public: B(int a): A(a),i(a) { cout << "construct B" << endl; } void displayb() { cout << "B:" << i << endl; } private: int i; }; class C:virtual public A //虚继承 { public: C(int a):A(2),i(a) { cout << "construct C" << endl; } void displayc() { cout << "C:" << i << endl; } private: int i; }; class D: public B, public C //多重继承 { public: D(int a, int b, int c, int d):A(a), B(b), C(d), i(c) //必须初始化虚基类X,X(d) { cout << "construct Z" << endl; } void displayd() { cout << "D:" << i << endl; } private: int i; }; int main() { D d(1,2,3, 4); d.displaya(); d.displayb(); d.displayc(); d.displayd(); }
|
运行结果:
编译器在实例化D时,之调用了一次虚基类的构造函数,忽略了虚基类A派生类B,C对续虚基类构造函数的调用,保证了虚基类的数据成员不会被初始化多次。