总结

教条地讲,面向对象编程具有“封装”、“继承”和“多态”三个特性。“封装”特性主要体现在私有成员和友元的使用上,“继承”则是运用基类和派生类减少代码重复,“多态”则是通过虚函数等一系列特性实现相同代码在运行期功能上的变化。我们在前两章已经多次运用了“封装”特性来编写代码。这一章我们则着重展开了“继承”和“多态”两个特性在语法上的体现。

“继承”在 C++ 语法上体现为基类和派生类的关系。

  • 继承分为公开继承、保护继承和私有继承三类。一般只有公开继承能体现“是”这种对象之间的关系。继承的分类决定了基类的非私有成员在派生类中的封装性。
  • 保护成员是当前对象的派生类可访问的私有成员。
  • 基类如同派生类的一个成员集合,可以出现在派生类的构造函数初始化列表中。构造派生类对象时,基类对象总是先被构造;析构的时候恰好相反,总是最后被析构。
  • 派生类的成员名和基类的成员名互相不冲突。换而言之,派生类的成员名只会隐藏基类的同名成员,而不是重写或覆盖。
  • 在必要的时候,可以通过 using 声明将基类的名字引入派生类,这可用于引入基类重载、继承构造函数、公开保护成员等情形。
  • 派生类可绑定到到基类的引用;指向派生类的指针可隐式转换到指向基类的指针;在期望基类对象的场合下派生类对象也可使用。这三者是多态的语法基础。

“多态”在 C++ 语法上体现为虚函数的使用。

  • 虚函数是指可以被派生类的同名函数覆盖的函数。当一个基类指针指向派生类对象,或者一个基类引用绑定到派生类对象上时,使用其虚函数将是对派生类成员的调用,而非对基类成员的调用。
  • RTTI(运行时类型识别)机制在多态的使用上发挥了作用。typeid 运算符可以获取一个多态类型的指针或引用的动态类型,dynamic_cast 可以实现安全的向下转型。
  • 通过建立纯虚函数,可以禁止一个类创建实例,从而只允许使用其派生类对象。
  • 虚析构函数是大有必要的。当使用多态时,为基类创建虚析构函数以防止内存泄漏。

除此之外,本章还提到了四种 C++ 风格转型 static_cast dynamic_cast const_cast reinterpret_cast,以及两个加强编译期检查的标识符 override final

最近更新:
代码未运行