首先需要对虚继承进行了解:(前一篇文章有讲解)
下面的图对一般继承和虚继承很好的解释。一般的继承为Bottom构造时先构造left和right,并且同时为left和right构造各自的Top,这样Bottom中有两个Top。而虚继承Bottom构造时屏蔽了left和right对Top的构造,而是使用自己对Top的构造。
下面以一个事例进行分析:
如图为继承关系:
A中有成员a
B中有成员b 经过继承: A:a 和 b
C中有成员c 经过继承: A:a 和 c
D中有成员d 经过继承: B:A:a,C:A:a,B:b,C:c和d
E中有成员e 经过继承: D:B:A:a,D:C:A:a,D:B:b,D:C:c,D:d,e
.h文件省略,以下为cpp文件:
A .cpp A::A(int a):m_a(a) //构造A { } void A::print() { cout << "A中的a" << m_a << endl; } B .cpp B::B(int a, int b):A(a),m_b(b) //构造B,调用A的构造 { } void B::print() { cout << m_b << "B中b" <<endl; cout << "B中继承的a" << this->m_a << endl; } C .cpp C::C(int a,int c):A(a),m_c(c) //构造C,调用A的构造 {} void C::print() { cout << m_c << "C中c" <<endl; cout << "C中继承A的a" <<endl; } D.cpp //构造D,调用A,B,C的构造,因为B,C是虚继承所以这里要调用A的构造函数,否则系统会调用A的默认构造函数,但不会通过B,C去调用A的赋值构造函数 D::D(int a1,int a2,int b,int c, int d):B(a1,b),C(a2,c),A(a2),m_d(d) {} void D::print() { cout << m_d << "D中的d" <<endl; cout << this->m_a << "D中的a" <<endl; cout << this->m_b << "D中的b" <<endl; cout << this->m_c << "D中的c" <<endl; } E.cpp //构造E,调用A,D的构造,同样因为B,C是虚继承,所以这里要调用A的构造函数,否则系统会调用A的默认构造函数,但不会通过D去调用A的赋值构造函数,说明虚继承具有传递性 E::E(int a1,int a2,int b,int c,int d,int e):D(a1,a2,b,c,d),A(a1),m_e(e) //调用A构造,D中对A的构造被屏蔽了 {} void E::print() { cout << m_e << "E中的e" <<endl; cout << this->m_a << "E中的a" <<endl; cout << this->m_b << "E中的b" <<endl; cout << this->m_c << "E中的c" <<endl; cout << this->m_d << "E中的d" <<endl; D::print(); B::print(); }
主函数:
#include "stdafx.h" #include <iostream> #include "E.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { E e(1,2,3,4,5,6); e.print(); /*D d(1,2,3,4,5); d.print();*/ //B *d = new D(1,2,3,4,5); //d->print(); system("pause"); return 0; }
足以见得,B,D,E中的a值都一样,在虚继承的过程中,其实是在派生类中添加了一个指针,指向基函数的成员。