虚继承的理解以及需要注意的问题

      首先需要对虚继承进行了解:(前一篇文章有讲解)

      下面的图对一般继承和虚继承很好的解释。一般的继承为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值都一样,在虚继承的过程中,其实是在派生类中添加了一个指针,指向基函数的成员。

虚继承的理解以及需要注意的问题

你可能感兴趣的:(继承)