首先需要对虚继承进行了解:(前一篇文章有讲解)
下面的图对一般继承和虚继承很好的解释。一般的继承为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值都一样,在虚继承的过程中,其实是在派生类中添加了一个指针,指向基函数的成员。