C++程序设计基础【三】
一、继承关系
在C++中,最一般的类被称为基类,而更具体地类被称为派生类,更一般的类也称为超类,更具体的类也称为子类
派生类继承了基类中的所有成员(有些例外),它还可以添加新成员
1.继承关系
最常用的继承是公共继承
基类中的公共成员称为派生类中的公共成员
要对基类和派生类中的函数使用相同的名称,需要重载或者重写的成员函数
构造函数、析构函数和赋值运算符未被继承,必须重新定义它们
在委托中,派生的成员函数使用类解析运算符(::)将其部分职责委托给基类
在调用中,派生类的构造函数在初始化期间调用基类的构造函数,这不需要类解析运算符
私有数据成员封装性更强,受保护数据成员可简化派生类的编码()
使用修饰符final防止被继承
李斯柯夫替代原则表明超类的对象必须始终可由子类的对象替代,而不改变超类的任何属性
私有继承不定义类型继承,它定义实现继承
2.关联关系
1.聚合关系
聚合是从聚合者到被聚合者的一对多关系
在聚合中,被聚合者的生命周期独立于聚合者的生命周期
(分开实例化)
2.组合关系
被包含者的生命周期取决于包含者的生命周期
被包含者是在包含者对象内创建的,它们不具有独立的生命周期
被包含者的生命周期取决于包含者的生命周期
(只有一个类实例化)
3.依赖关系
类A依赖类B,需要使用类B
二、多态性
1. 多态性
1.多态性的条件
多态性的三个条件分别是指针或者引用、可交换对象和虚函数
C++建议我们总是为多态性的基类定义一个显式析构函数,并使其称为虚函数,使用虚析构函数可以防止多态性中可能发生的内存泄漏
2.绑定
1.静态绑定
静态绑定出现在一个函数包含多个定义时,但编译器在编译程序时知道要使用哪个版本的定义
2.动态绑定
当编译期间对象未知时,需要进行动态绑定
3.运行时类型信息
1.使用typeid运算符
使用typeid(*).name返回类名的长度和名称
2.使用dynamic_cast运算符
使系统增加大量开销,不建议使用
2.抽象类
具体类可以实例化并创建改类型的对象
抽象类是具有至少一个纯虚函数的类
无法实例化抽象类,因为抽象类中没有纯虚成员函数的定义
接口时抽象类的一种特殊情况,其中所有成员函数都是纯虚函数
3.多重继承
1.虚基继承
对于多重继承中重复的共享数据成员的问题的解决方案之一是使用虚基继承,中间类可用virtual关键字从公共基继承,设置共有的数据成员为受保护数据成员
2.混入类
mixin类是另一个解决方案,mixin类永远不会被实例化,但mixin类可以向其他类添加数据成员