C++基础 多重继承引发的 虚基类与虚继承(基类被虚继承 就称为虚基类?)

//-- 不采用虚基类的方式
classA.h

#pragma once
#include "grand.h"
class A :public Grand
{
public:
	A(int a, int b, int c);
	~A();

	void testTongMingHanShu();
	int m_iTingMIngBianLiang;
private:

};

A::A(int a, int b, int c) :Grand(a)
{
	printf("A的构造a= %d\n", a);
}

A::~A()
{
}

void A::testTongMingHanShu(){
	printf("A的同名函数\n");
}

classA2.h

#pragma once
#include "grand.h"
class A2:public Grand
{
public:
	A2(int i);
	~A2();

private:

};

A2::A2(int i) :Grand(i)
{
	printf("A2类的构造i = %d\n", i);
}

A2::~A2()
{
}

classB.h

#pragma once
#include "classA.h"
class B
{
public:
	B();
	~B();
	void testTongMingHanShu();

	int m_iTingMIngBianLiang;
private:

};

B::B() 
{
}

B::~B()
{
}
void B::testTongMingHanShu(){
	printf("B的同名函数\n");
}

classC.h

#pragma once
#include "classA.h"
#include "classB.h"
#include "classA2.h"
class C:public A, public A2, public B
{
public:
	C(int a, int b, int c);
	~C();

private:

};

C::C(int a, int b, int c) :A(a,b,c), A2(b), B()
{
}

C::~C()
{
}

grand.h

#pragma once
class Grand
{
public:
	Grand(int i);
	~Grand();

	int getValue();
private:
	int m_value;
};

Grand::Grand(int i) :m_value(i)
{
	printf("Grand类的构造m_value = %d \n", m_value);
}

Grand::~Grand()
{
}

int Grand::getValue(){
	return m_value;
}

main.cpp

// ConsoleApplication17.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "classB.h"
#include "classC.h"

int _tmain(int argc, _TCHAR* argv[])
{
	C c(9,8,7);
	//ambiguous  c的基类ab都有这个函数和变量
	//c.testTongMingHanShu();
	//c.m_iTingMIngBianLiang;
	c.A::testTongMingHanShu();
	// 因为grand类中的内容被继承了两次
	//c.getValue();
	printf("getValue = %d \n", c.A::getValue()); //9
	printf("getValue = %d \n", c.A2::getValue());//8
	/*
	C类的基类A A2都继承了grand类,  grand类的构造函数被A A2执行了两次,在A A2中分别都有一份grand的存在,在C类中包含了A A2,即C类重复继承了grand类,
	*/

	//-- 为了防止上述的 不合理,可与采用虚继承。即A A2都从grand类虚继承,一个都不能少。
	
	return 0;
}

//-- 采用虚基类的方式
与上述的不同之处在于
1.继承类 加virtual虚继承 基类
2.最终继承类 完成虚基类的初始化工作
classA.h

#pragma once
#include "grand.h"
//虚继承
class A : public virtual Grand
{
public:
	A(int a, int b, int c);
	~A();

	void testTongMingHanShu();
	int m_iTingMIngBianLiang;
private:

};

A::A(int a, int b, int c) :Grand(a)
{
	printf("A的构造a= %d\n", a);
}

A::~A()
{
}

void A::testTongMingHanShu(){
	printf("A的同名函数\n");
}

classA2.h

#pragma once
#include "grand.h"
//-- 虚继承
class A2 :virtual public Grand
{
public:
	A2(int i);
	~A2();

private:

};

A2::A2(int i) :Grand(i)
{
	printf("A2类的构造i = %d\n", i);
}

A2::~A2()
{
}

classC.h

#pragma once
#include "classA.h"
#include "classB.h"
#include "classA2.h"
class C:public A, public A2, public B
{
public:
	C(int a, int b, int c);
	~C();

private:

};
//-- 最终类初始化虚基类
C::C(int a, int b, int c) :A(a, b, c), A2(b), B(), Grand(c)
{
}

C::~C()
{
}

main.cpp

// ConsoleApplication17.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "classB.h"
#include "classC.h"

int _tmain(int argc, _TCHAR* argv[])
{
	C c(9,8,7);
	//ambiguous  c的基类ab都有这个函数和变量
	//c.testTongMingHanShu();
	//c.m_iTingMIngBianLiang;
	c.A::testTongMingHanShu();
	//因为grand类中的内容被A A2继承了二次(因为是虚继承,所以A A2共享虚基类grand同一份实例)
	//-- 采用虚继承。即A A2都从grand类虚继承,A A2虚继承一个都不能少。
	printf("getValue = %d \n", c.getValue()); //7
	printf("getValue = %d \n", c.A::getValue()); //7
	printf("getValue = %d \n", c.A2::getValue());//7
	/*
	1.虚继承就是在继承时加 virtual字段 
	2.在最终的继承类完成虚基类的的初始化 工作(本例子是孙子类C的构造函数中 对grand类进行初始化, A A2的构造函数中初始化列表不能省 省则报错)
	3.先追溯到哪个虚基类,就先构造哪个虚基类的子内容
	*/
	
	return 0;
}

下述 几个文件都未变过
classB.h

#pragma once
#include "classA.h"
class B
{
public:
	B();
	~B();
	void testTongMingHanShu();

	int m_iTingMIngBianLiang;
private:

};

B::B() 
{
}

B::~B()
{
}
void B::testTongMingHanShu(){
	printf("B的同名函数\n");
}

grand.h

#pragma once
class Grand
{
public:
	Grand(int i);
	~Grand();

	int getValue();
private:
	int m_value;
};

Grand::Grand(int i) :m_value(i)
{
	printf("Grand类的构造m_value = %d \n", m_value);
}

Grand::~Grand()
{
}

int Grand::getValue(){
	return m_value;
}
上一篇:labview调用opencv 如何封装dll labview图像转到opencv图像


下一篇:芭蕾挑战(FLAG)第一天