文章目录
1.继承的定义
2.继承的关系和访问限定符
2.1内容
2.2继承父类成员访问方式的变化
规律:private成员经过如任何继承都会是不可见的;
public成员和protected成员在和各类继承中两者选其小;
struct和class之间类成员类型和继承方式的不通风
struct默认的成员类型和继承方式都是private
class默认的成员类型和继承方式是:public
不可见和private的区别
不可见是类内和类外都不可以使用
private是类内可以使用,类外不可使用;
继承使用的成员的类型只有两中public’和protect没有private原因件上private’的继承
3.父类和子类对象赋值(条件:共有继承)
定义:派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用。这里有个形象的说法叫切片或者切割。寓意把派生类中父类那部分切来赋值过去。
子类给父类赋值
这里的赋值没有产生类型转换;没有产生转换用的常量;
原因:在public继承的条件下子类是父类的一个特殊;(简称切片)
示例图文解释
这里person的引用这里指的是student的上半部分的别名;
** 注意**
这里只有成员变量进行了继承;成员函数没有进行继承;
父类不可以传给子类
4.继承中的作用域
4.1重定义
父类和子类存在相同名字的变量或函数名
这里的子类使用重定义的变量或函数按照就近原则;子类有就先使用子类的;
当这种情况发生后在子类中的重命名的函数后变量
想要调用父类的变量或函数时间需要加上作用域
5.子类的默认成员函数
5.1构造函数
子类没有写构造函数时;将会调用父类的构造函数
所以子类需要自己写一个构造函数;
这里构造函数会将父类看作一个一个对象和子类中的成员变量进行同时进行初始化;
即子类将会将类中的类型分为自定义类型,内置类型,父类类型
5.2拷贝构造函数
5.3运算符重载
将父类赋值,再赋值子类成员;
5.4析构函数
5.1 子类的析构函数和父类的函数构成隐藏;两者都会被编译器命名为destructor的函数名
5.2使用作用域来调用父类
但是这里可以看出父类的析构多调用了一次;
原因:
子类和父类析构顺序是:先子后父
由于c++祖师爷害怕有些人会出现先父后子的问题(该问题将会将父类中的数据进行两次析构)将子类的析构函数设计成自动调用父类的析构函数 ;
实现一个不可继承的类
方法一:将父类的构造函数私有化:
这里构造函数在子类中将会无法访问;
方法二:c++11中添加了final修饰符(写在类名后面,)
这里做的特别绝;子类在继成时;就被中止了;
6.继承与友元
在继承中;子类不可使用父类的友元函数;
7.继承和静态变量
**基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。**无论派生出多少个子
类,都只有一个static成员实例 。
子类会继承父类的静态变量;但是继承的是使用权,而不是拥有权;
8.多继承
8.1多继承和单继承的对比
8.2多继承的问题(菱形继承)
示例:
问题:数据多余;二异性;
解决方法:
1.虚继承
c++祖师爷引出了虚继承(virtual)
注意:
菱形继承比一定是四个类;可以是多个;
2。加作用域来改变数据中内容;
虚继承原理:
虚继承前:
虚继承后:
①:虚继承前A的位置;
②:虚继承后A的位置
③:②相对①的偏移量;
这里虚继承引出了②偏移量 (当前A的内存位置相对之前③原来A的位置)
** 虚继承的本质:少存了一份A,所以只要A够大效果越大**
示例
9.继承和组合的区别:
组合
组合:在D类中定义C类的变量;在D类的成员函数中使用C类变量;
继承和组合的对比
使用范围比较:
继承:子类可以使用父类的保护成员;类外定义的变量可以使用父类的成员;(is a)
组合:组合类使用被组合类的私有成员;类外也不可使用被组合类的成员;(has a)
藕连性
继承:子类和父类的藕连性很强:子类改变一个成员变量名字,父类也会改变;
组合:组合类和被组合类的藕连性不高,被组合类只有改变共有时才会影响组合类;
左为 继承;右为组合
** 所以公司平常使用组合多一些**