C++继承笔记

概念

复用代码的一种方式,子类可以根据不同的继承方式复用父类的成员,可以在复用的基础上进行扩展。

class Person
{
public:
	Person(int age=18,string name="张三")
		:_age(age)
		,_name(name)
		{}
	void print()
	{
		cout << "name:" << _name << endl;
		cout << "age:" << _age << endl;
	}
protected:
	int _age;
	string _name;
};

class stu:public Person
{
protected:
	int id=111111;
};

int main()
{
	stu a;
	a.print();
	return 0;
}

对于继承方式比较重要的几个点
1.父类的private成员子类无论什么方式继承在子类中都是不可见的
2.其他的权限基本上是在成员和继承方式中取权限较小的那个

对象赋值转换

子类的成员总是不少于父类的,所以我们可以使用子类来对一个父类对象进行赋值、初始化,父类的指针和引用也可以指向子类。
反过来就不行,因为父类的成员没有子类多。
这种方式叫做切片,但是没有真的切
image.png

	stu s;
	stu* sp;
	Person* pp = &s;//指针
	Person& p = s;//引用
	Person p1 = s;//对象

	sp = (stu*)pp;//父类的指针可以通过强转赋值给子类的指针,有可能越界

关于继承中的作用域

父子类的作用域是相互独立的,如果父子类中有同名的成员,这个情况构成隐藏,也叫重定义,默认只会访问子类的成员,也可以通过指定父类作用域的方式访问父类的同名成员。
如果是函数重定义只要函数名相同就构成重定义。

子类的默认成员函数

一、构造函数
如果父类的构造函数被我们定义了,那在子类的构造函数中必须显式调用父类的构造函数,子类无法初始化父类的成员变量,但是可以改变父类成员变量的值。
二、拷贝构造和重载=
子类这两个函数都是要完成父类的拷贝构造和赋值
三、析构函数
子类的析构函数必须先执行析构子类的成员,再执行父类的析构函数,如果反过来的话有一些子类在执行的时候要使用父类的一些数据,但是这个时候父类的成员已经被释放了,会导致问题,编译器会强制最后执行父类的析构函数

继承中的友元

友元是无法继承的,父类的友元函数无法访问子类的保护和私有,没了

难点 菱形继承和菱形虚拟继承

image.png
如果我们代码中遇到这种情况,就会发生一些糟糕的事情
当b类和c类都继承了a类中的成员,
而号d类又同时继承了b类和c类,
这个时候d类中就会有两份a中的成员,
一份是b类继承的一份是c类继承的,
这个时候通过d类成员访问a类中的成员就会有二义性,
你要的是b里的还是c里的a
同时也会造成数据冗余
访问也可也正常访问,我们只需呀指定一下类域就行了

class a
{
public:
	int _a = 1;
};
class b: public a
{
public:
	int _b = 2;
};
class c: public a
{
public:
	int _c = 3;
};
class d:public b,public c
{
public:
	int _d = 4;
};
void main()
{
	d dd;
	cout << dd.b::_a << endl;
}

这种方法显然不怎么实用,c++也提供了另一种解决方案
在b和c继承方法的前面加上关键字 virtual

class a
{
public:
	int _a = 1;
};
class b:virtual public a
{
public:
	int _b = 2;
};
class c:virtual public a
{
public:
	int _c = 3;
};
class d:public b,public c
{
public:
	int _d = 4;
};
void main()
{
	d dd;
	cout << dd._a << endl;
}

添加virtual关键字之后这种方式叫做虚继承
虚继承之后d类对象中就只有一份a类对象中的成员。
我们来简单瞅一眼菱形虚拟继承后的d对象存储布局就能知道他是怎么做到的
image.png
这个玩意很复杂,不要去写菱形继承

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值