C++继承

一、什么是继承

1、当遇到问题时先查看现有的类是否能解决一部分问题,如果有则继承该类,并在此基础上扩展以此解决问题,从而缩短解决问题的时间(代码复用)

2、当遇到一个大而复杂的问题时,可以把大问题拆分成若干个不同的小问题,然后为每个小问题设计一个类来解决,最后通过继承的方式把这些类汇总到一个类中,从而解决大问题,以此降低问题的难度,可以同时让多个程序员共同解决大问题

派生类继承基类 子类继承父类

二、继承的语法

1、继承表
class son : 继承表 [继承方式 父类名1, 继承方式 父类名2, ...]
{
  	成员变量;
public:
    成员函数;
};
2、继承方式

public

protected

private

3、继承的特点

①C++中的继承可以有多个父类

②子类会继承父类的所有内容,是否能用另说

③子类对象可以向他的父类类型转换(缩小),但是父类对象不能向子类类型转换(放大)

父类指针或引用可以指向子类对象,子类指针或引用不能指向父类对象

前提:必须以public继承父类

Base* b = new son;	//	true
Base& b = son;		//	true

Son* s = new Base;	//	false
Son& s = base;		//	false

④子类会隐藏父类的同名成员(成员变量、成员函数),不构成函数重载,因为作用域不同

同名成员被隐藏后,在子类中直接访问到的是子类的同名成员

但是可以通过 父类名::同名成员名 的方式指定访问父类同名成员

⑤在执行子类的构造函数的初始化列表时,会按照继承表的顺序来执行父类的构造函数,默认执行的是父类的无参构造,但也可以在子类的初始化列表中显式地调用父类的有参构造,然后再执行类类型成员的构造函数,最后执行子类的构造函数

Son(int num){}				//	调用Base的无参构造
Son(int num):Base(val){}	//	调用Base的有参构造

⑥在子类的析构函数执行结束后,再调用类类成员的析构函数,最后按照继承表的逆序调用父类的析构函数

⑦当子类执行拷贝构造时,默认下只会调用父类的无参构造,但是这是有问题的,因此需要在子类的拷贝构造函数的初始化列表中显式地调用父类的拷贝构造函数

Son(const Son& that):Base(that){}	//	调用Base的拷贝构造
//	父类引用可以指向子类对象

⑧当子类执行赋值函数时,默认下不会调用父类的赋值函数,如果需要调用父类的赋值函数,可以在子类的赋值函数中通过域限定符显示地调用父类的赋值函数

Son& operator=(const Son& that)
{
    Base::operator=(that);	//	调用Base的赋值操作函数
}

三、继承方式与控制访问属性

1、访问控制属性对成员的访问限制
属性范围
public可以在任意位置访问
protected只能在类内和子类中访问
private只能在类内访问
2、继承方式的影响

①父类的成员是否能直接在子类中直接访问,取决于父类中的访问控制属性,不受子类的继承方式影响

②子类的继承方式能决定父类成员被子类继承后,在子类中变成什么样的访问控制属性,详情见表格

父类中的属性public继承protected继承private继承
publicpublicprotectedprivate
protectedprotectedprotectedprivate
privateprivateprivateprivate

③只有以public方式继承父类,父类的指针或引用才能指向子类对象,这也是多态的基础

四、多重继承和钻石(菱形)继承

1、多重继承

当一个子类继承多个父类时,此时称为多重继承,会按照继承表的顺序在子类中排列父类的内容,当使用父类指针指向子类对象,编译器会自动计算出该父类的内容在子类中的位置,并让父类指针指向该位置,所以可能会出现使用同一个子类指针给不同的父类指针赋值后,地址编号不同的情况

2、钻石继承、菱形继承

假设有一个类A,类B和类C都分别继承了类A,又有类D继承了类B、类C,一个类的父类有共同祖先类时,形成了钻石(菱形)继承

问题:

①类B、类C中各自都有类A的内容

②类D会继承类B、类C的所有内容,就导致了类D中继承了两份类A的内容

③当类D对象去访问类A的内容时,编译器不能确定访问的是哪份类A的内容,有歧义,会报错

3、虚继承

使用virtual关键字去修饰继承表时,此时变成虚继承

此时子类中会多出一个成员变量:虚指针,该指针会指向父类的内容,并且当该子类被继承时该虚指针会一起被继承,如果此时形成钻石继承时,孙子类中就会有多个指向相同位置的虚指针,此时编译器会比较这些虚指针指向的内容是否一致,如果是则只继承一份

总结:通过虚继承可以解决钻石继承中的访问共同祖先类内容会有歧义的内容

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值