第25章总结
本节阅读量:至此,我们对 C++ 继承和虚函数的探索告一段落。继续前进时,C++ 还有许多其他领域等待我们探索。
章节摘要
C++ 允许您创建指向派生对象的基类指针或引用。当我们想编写一个可以处理任意派生类对象的函数或数组时,这非常有用。
如果没有虚函数,指向派生对象的基类指针和引用只能访问基类版本的成员变量和函数。
虚函数是一种特殊函数,它会解析为基类和派生类层次中最底层的派生版本(称为重写)。要被视为重写,派生类函数必须具有与基类虚函数相同的签名和返回类型。一个例外是:如果基类函数返回指向基类的指针或引用,则允许重写函数返回指向派生类的指针或引用。
一个旨在作为重写的函数应该使用override说明符来确保它实际上是一个重写。
final说明符可用于防止重写函数或类被继承。
如果你打算使用继承,应该将析构函数设置为 virtual。这样通过基类指针删除对象时,才会调用正确的析构函数。
您可以使用作用域解析运算符直接指定所需函数的类版本,从而绕过虚函数解析,例如 Base::getName()。
静态绑定发生在编译器遇到直接函数调用时。编译器或链接器可以直接解析这些函数调用。当使用函数指针时,会发生动态绑定。在这些情况下,直到运行时才能解析将调用哪个函数。虚函数使用动态绑定和虚函数表来确定要调用哪个版本的函数。
使用虚函数是有代价的:调用虚函数需要更长的时间,虚函数表的必要性使每个包含虚函数的对象的大小增加了一个指针。
通过在虚函数原型末尾添加 “=0”,可以使虚函数成为纯虚函数(抽象函数)。包含纯虚函数的类称为抽象类,不能被实例化。继承纯虚函数的类必须为它们提供具体定义,否则也会被视为抽象类。纯虚函数可以有函数体,但它们仍然被视为抽象函数。
接口类是不包含成员变量、且所有函数都是纯虚函数的类。接口类通常以大写字母 I 开头命名。
virtual 基类是一种只会被包含一次的基类,无论它在继承体系中被继承了多少次。这常用于存在菱形继承的情况。
当将派生类对象赋值给基类对象时,基类对象只会接收派生对象中基类部分的副本。这称为对象切片。
dynamic_cast可用于将指向基类对象的指针转换为指向派生类对象的指针。这被称为向下转换。转换失败将返回空指针。
为继承类重载 operator« 的最简单方法,是为基类编写 operator«,然后调用虚成员函数进行打印。