面向对象的三大特性:封装,继承,多态
继承
本质是一种复用
继承定义
继承关系和访问限定符
继承父类成员访问方式的变化
保护和私有之前是没有区别的,在继承这里私有在子类是看不见的 ,这里保护可以看见
子类继承的访问,是min(父类,子类)父类和子类中小的那个访问权
class继承方式不写默认是私有继承,struct默认是公有(不要不写,建议写上)
私有和不可见的区别:
不可见(类比私房钱)类里面和类外面都不可见
私有(彩礼)类外面不能使用,类里面可以使用
总结:私有不可见,其他取权限小的那一个
赋值兼容规则
publi,父类和子类是is-a关系
有些相近类型会发生隐式类型转换
r不能引用d因为d会生成临时对象,具有常性 要加const
is-a我就是你,has-a组合
这里没有产生临时对象 , 这里生成临时对象,然后再拷贝构造(加const)
父子兼容规则(切割、切片)
子能给父,子有的父都有
隐藏
子类同名成员隐藏父类同名成员
子类继承父类后还可以定义相同的变量,因为他们属于不同的域
就近原则默认情况下走自己的的
继承中同名的成员函数,函数名相同就构成函数隐藏(访问父类就要指定作用域)
指定作用域
要把父类当成一个完整的对象去初始化,不是单个成员初始化
不写会调用父类的
这样调用
子类不写拷贝构造,默认会调用父类的拷贝构造
子类写了自己的拷贝构造就调用自己的拷贝构造,如果自己的拷贝构造涉及父类变量(name是父类的)列如下面的s
,s中的name是继承父类的那么。传他父类的指针或者引用
问题:父类的拷贝构造要传一个父类过去,怎么办?,把子类给一父类的引用/指针/对象
虽然传的s是子类但是子类s传给父类的引用p,引用的是子类对象中父类的那一部分
想要调用父类的函数重载(=)栈溢出了(死循环)
这里构成了隐藏关系,一直以调用自己的operator=调用不到父类的operator=
所以记得指定作用域
析构函数的显示调用失败
前面的函数都可以显示调用 析构函数的显示调用失败
因为子类的析构函数跟父类的析构函数形成隐藏关系(在这里~Person实际上析构的是~Student)
不是同名为什么构成隐藏?因为多肽原因析构会被统一处理成 destructor,
要想访问只能指定作用域
析构顺序是先父后子会有风险,因为子类能够调用父类函数或成员,如果父类已经析构,子类还没有结束,子类就会出错
(因为子类会访问父类成员,但是析构先父后子,子类就崩了)
如果析构函数让你自己调用就可能先父后子 ,为了保证析构安全,父类析构函数不需要显示调用,子类析构函数调用结束后会自动调用父类析构函数,保证先子后父