跳到主要内容

虚函数

📝

基类通常都应该定义一个虚析构函数,即使该函数不执行任何实际操作也是如此

C++ 中,基类将类型相关的函数与派生类不做改变直接继承的函数区分对待,一种是基类希望派生类直接继承而不要改变的函数;另一种是基类希望派生类进行覆盖的函数,这样的函数通常在基类中定义为 虚函数(virtual function)

对于某些函数,基类希望它的派生类各自定义适合自身的版本,此时基类就将这些函数声明成 虚函数(virtual function)

任何构造函数之外的非静态函数都可以是虚函数。关键字 virtual 只能出现在类内部的声明语句之前而不能用于类外部的定义

如果基类声明了一个虚函数,则该函数在派生类中隐式的也是虚函数

当我们使用指针或者引用调用函数的时候,该调用将被动态绑定。根据引用或者指针所绑定的对象类型不同,决定执行函数的版本

动态绑定

在调用一个函数时,我们既能使用基类的对象调用该函数,也能使用派生类的对象调用该函数,实际传入的对象类型将决定到底执行函数的哪个版本

上述过程中,函数的运行版本由实参决定,即在运行时选择函数的版本,所以动态绑定又被称为 运行时绑定(run-time binding)

📝

在 C++ 语言中,当我们使用基类的引用(或指针)调用一个虚函数时将发生动态绑定

final 和 override 说明符

C++11 新标准中可以使用 override 关键字来说明派生类中的虚函数,使意图清晰的同时也能让编译器发现一些错误

class A{
public:
void f1();
void f2();
}

class B :A{
public:
void f1() override; // 正确
void f2(int) override; // 错误,A 中没有 f2(int) 这样的函数
}

我们还能将某个函数指定为 final ,指定后任何尝试覆盖该函数的操作都将引发错误

class A{
public:
void f1();
void f2() final;
}

class B :A{
public:
void f1() override; // 正确
void f2() override; // 错误 f2 在 A 中已经声明了 final
}

reference

  • 《C++ Primer》—— 第五版