ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2021-09-26 12:05:07  阅读:165  来源: 互联网

标签:grand 继承 基类 C++ int A2 Grand include public


//-- 不采用虚基类的方式
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;
}

标签:grand,继承,基类,C++,int,A2,Grand,include,public
来源: https://blog.csdn.net/baidu_19552787/article/details/120485587

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有