C++知识总结复习04

C++知识总结复习04,第1张

继承

继承机制面向对象程序设计使代码可以复用的最重要手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称为派生类。

继承呈现了面向对象程序设计的层次结构

体现了由简单到复杂的认知过程,继承的类设计层次的复用

1.基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,在语法上限制派生类对象不管在类里面还是类外面都不能去访问它

2.基类private成员在派生类中是不能被访问,基类的私有成员在子类都是不可见的。如果基类的成员需要在子类被访问但不想在类外访问,就定义protected,可以看出保护成员限定符是因继承才出现的

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

在继承体系中基类和派生类都有独立的作用域

子类和父类中有同名成员,子类成员将屏蔽父类同名成员的直接访问,这种情况叫隐藏

也叫重定义(如果需要访问需要指明类域显示访问)

ps:只需要函数名相同就可以构成隐藏

关于子类的默认成员函数

在VS2013环境下(其他编译器大概也是)

通过内存及部分实验观察得知

1.先调用父类的构造函数再调用子类的构造函数

2.父类位于低地址,子类位于高地址

3.析构时,会先析构子类再析构父类(这符合栈的顺序,父类是先入栈的)

友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员

基类定义了static静态成员,则整个继承体系里面只有一个这样的成员,无论派生出多少个子类,都只有一个static成员实例

由于C++支持多继承

则会引发菱形继承的问题,即二义性和代码冗余

解决方式:通过虚继承

如果有两个类A,B继承了公共的祖先,然后C同时继承了A,B

通过虚继承,祖先只创建一份,放到虚基表中,A,B中存放着这张表的地址

这张表中存有相对于公共祖先位置的偏移量,通过该偏移量可找到唯一的祖先

继承和组合的关系

组合:在类中直接定义类

耦合度低。

继承 is-a

组合has-a

根据不同的实际场景使用即可

多态

静态的多态:函数重载,看上去相同的函数能处理不同的事情(编译时实现)

动态的多态:不同对象做同一件事情有不同的结果(运行时实现)

条件
必须通过基类的指针或引用

被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写

重写三个条件:函数名,参数,返回值必须相同

特殊情况:

1.协变:基类与派生类函数返回值类型允许不同

2.父类+virtual,子类只需满足三同条件即可,即可以不加virtual

原本目的:考虑析构函数的重写(如需要通过父类去释放子类时)

相关关键字

final:
修饰函数,表示该虚函数不能再被重写

override:

检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错

抽象类

在虚函数的后见面写上=0,则这个函数为纯虚函数,包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象,派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象,纯虚函数规范了派生类必须重写,另外出喜怒函数更体现处了接口继承

多态的原理:

虚函数表

如果该类中的非静态成员有虚函数,则编译器会为其形成一张虚函数表,并把其地址放在该实例化后的头部(可能不一定,vs2013是这样的)

该类所有对象共用一张该虚函数表(说明该虚函数表存放在常量区)

当继承同一祖先的不同类(假设都有虚函数完成重写),当我们调用该函数时,实际上是去虚表中找对应的重写函数(这就是为什么会传父类的指针或引用,我们只需要找到虚表中对应的重写函数,并不关心这个类是哪一个,即在运行中实现多态)

多继承中的虚函数表

存在多份虚表

多继承派生类的未重写的虚函数在一个继承基类部分的虚函数表中

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1330991.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-12
下一篇 2022-06-12

发表评论

登录后才能评论

评论列表(0条)

保存