c++中的继承

众所周知,继承是c++中的一个特性,我们今天了解一下c++中单继承 多继承以及菱形继承。

何为继承,继承是面向对象语言中可以使代码复用的一个机制。我们可以保持我们原有类的基础上,扩展一些新的功能,新扩展的类被称为派生类,而原有的类叫做基类。

那么它的用法如下

#include<iostream>
using namespace std;

class A
{
public:
	void testfunc()
	{}
	int _a;
};

class B1 :public A  //B1类公有的继承类A,B1类被称为派生类,而A类叫基类
{
public:
	int _b;
};

class B2 :public A
{
public:
	int _b2;

};

其中在继承的基类前的public为继承方式,一共有public protected private三种继承方式。

                 

类成员/继承方式public继承protected继承private继承
基类的public成员派生类的public派生类的protected派生类的private
基类的protected成员派生类的protected派生类的protected派生类的private
基类的private成员派生类中不可见派生类中不可见派生类中不可见

派生类对象可以赋值给基类对象/ 基类指针 /基类引用

#include<iostream>
using namespace std;

class A{
public:
	void testfunc()
	{}
	int _a;
};

class B1 :public A{
public:
	int _b;
};

class B2 :public A{
public:
	int _b2;

};

class C :public B1, public B2
{
public:
	int _c;

};

int main()
{
	cout << sizeof(C) << endl;
	C d;
	C M;
	//d._c = 2;
	//d._b = 4;
	//d.B::_a = 3;
	//d.B2::_a = 5;
	B2 c = d; //派生类可以赋值给基类的对象
	B2 *d = &d; //派生类可以赋值给基类的指针
	B2 &m = d;  //派生类可以赋值给基类的引用

	B2* n = &d;
	n = &d;
	C* f = (C*)n;//基类的指针可以通过强制类型转换赋值给派生类指针

	system("pause");
//	M = c; 基类不能给派生类赋值
	return 0;
}

这段代码还出现了菱形继承,在说菱形继承之前,我们首先要知道,继承分两种,单继承和多继承。

单继承:就是子类只有一个直接父类。

多继承:子类有两个或以上的直接父类,菱形继承是多继承的一种

 

菱形继承

什么为菱形继承,比如我们定义了一个类A,然后分别定义两个类B1和B2,这两个类都是类A的派生类,然后我们现在又定义了一个类C,这个类C同时继承了类B1和B2.那么这时会出现什么问题呢,这时,如上图代码所示,其实我们计算一下类C的大小,就会发现sizeof之后大小为20,我们每个类中只定义了一个int的变量,这就说明了,我们类C继承的类B1和B2中都包含了类A的成员变量,于是我们在主函数中如果创建一个类C的对象,然后去给这个对象中包含的父类的A中的成员变量去赋值,其实是不可以的,因为编译器不知道我们调用的是从类B1还是类B2中继承的变量,这就是菱形继承的二义性。当然两份的数据也会导致数据冗余。

二义性问题可以通过显式访问的是哪个父类的成员解决,但是无法解决数据冗余问题。

解决菱形继承问题?

解决菱形继承的办法

虚拟继承就可以解决二义性和数据冗余的问题,即在继承方式前面加virtual,然后在访问的时候,就会有两个指针,被称为虚基表指针,两个表叫虚基表,虚基表中存的偏移量,通过偏移量就可以找到这个值。

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值