C++基础14-类和对象之多继承与虚继承

本文深入探讨了C++中的多继承和虚继承概念,解析了如何通过虚继承解决多继承中基类成员的二义性问题,以及如何避免公共基类成员的多次拷贝。

多继承:一个类有多个直接基类的继承关系称为多继承

总结:

1、一般将具有菱形样式继承方式的某些类声明为虚继承

3、虚继承的主要目的是为了防止二义性

2、虚继承就是在继承方式前加virtual

如果一个派生类从多个基类派生,而这些基类有一个共同的基类,则在对该基类中声明的名字进行访问时,可能产生二义性

如:

虚继承virtual

如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中声明的名字进行访问时,可能产生二义性

如果在多条继承路径上有一个公共的基类,那么在继承路径的某处 汇合点,这个公共基类就会在派生类的对象中产生多个基类子对象 要使这个公共基类在派生类中只产生一个子对象,必须对这个基类声明为虚继承,使这个基类成为虚基类

虚继承声明使用关键字 virtual

多继承:

#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;


#if 0
//多继承案例
//家具类
class Furniture
{
};

//将父亲类继承爷爷类  改成虚继承, 防止儿子在多继承我的时候,出现爷爷中的变量会拷贝多份。
class Bed :public Furniture
{
public:
	void sleep() {
		cout << "在床上睡觉" << endl;
	}
};


class Sofa :public Furniture
{
public:
	void sit() {
		cout << "在沙发上休息" << endl;
	}
};

//沙发床
class SofaBed :public Bed, public Sofa
{
public:
	void SleepAndSit() {
		sleep();
		sit();
	}
};
void test01() {
	Bed b;
	b.sleep();

	Sofa s;
	s.sit();

	cout << " ------ " << endl;

	SofaBed sb;
	sb.SleepAndSit();
}
#endif

//家具类
class Furniture
{
public:
	int m; //材质
	Furniture() {
		m = 0;
	}
};

//将父亲类继承爷爷类  改成虚继承, 防止儿子在多继承我的时候,出现爷爷中的变量会拷贝多份。
class Bed :virtual public Furniture
{
public:
	Bed() {
		m = 1;
	}
	void sleep() {
		cout << "在床上睡觉" << endl;
	}
};


class Sofa :virtual public Furniture
{
public:
	Sofa() {
		m = 2;
	}
	void sit() {
		cout << "在沙发上休息" << endl;
	}
};

//沙发床
class SofaBed :public Sofa,public Bed
{
public:
	SofaBed() {
		//m = 3;
	}
	void SleepAndSit() {
		sleep();
		sit();
	}
};

void test01() {
	SofaBed s;
	cout<<s.m<<endl;  //将父亲的继承方式改为虚继承。这样在s中就只有一个爷爷中的数据成员
		        //否则在s中分别有从Bed和Sofa中继承的m,s去访问 会有指向不明确的说法
	//情况1:当SofaBed的构造函数中m=3时,s.m=3
	//情况2:当SofaBed的继承方式为public Sofa,public Bed时, s.m=1
	//情况3:当SofaBed的继承方式为public Bed,public Sofa时,s.m=2
	//当前继承情况下:
	cout << s.Furniture::m << endl;//1
	cout << s.Bed::m<<endl; //1
	cout << s.Sofa::m<<endl;//1
	
}
int main(void)
{
	test01();

	return 0;
}
#endif

虚继承:

#if 1
#include<iostream>
using namespace std;
class GrandPa {
public:
	int m;
	GrandPa() {
		cout << "GrandPa()" << endl;
	}
};
class Parent1 :public GrandPa {
public:
	Parent1() {
		cout << "Parent1()" << endl;
	}

};
class Parent2 :public GrandPa {
public:
	Parent2() {
		cout << "Parent2" << endl;
	}
};
class Son :public Parent1, public Parent2 {
public:
	Son() {
		cout << "Son()" << endl;
	}
};
void test01() {
	Son s;
}
/*
GrandPa()
Parent1()
GrandPa()
Parent2
Son()
*/
void test02() {
	Son s;
	//s.m; //直接访问编译错误 不明确 此时的m是Parent1还是Parent2还是Grandpa
	cout<<s.Parent1::m<<endl;
	cout<<s.Parent2::m<<endl;
	cout<<s.GrandPa::m<<endl;
}
/*
GrandPa()
Parent1()
GrandPa()
Parent2
Son()
-858993460
-858993460
-858993460
*/
int main() {
	//test01();
	test02();
	return 0;
}
#endif

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chde2Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值