虚函数自C++的开始就作为动态多态性的一种手段。然而,早期并没有语法机制来强制编译器检查派生类中虚函数重写的正确性。在C++11之后,‘override’关键字成为了额外编译器检查的工具。
如果没有‘override’,编译器不能保证该函数确实重写了基类的方法。签名中的错误(例如,错误的类型或const)会导致在派生类中创建新函数(“遮蔽”),这会破坏多态性并使调试变得困难。
在派生类中声明虚函数时使用‘override’允许编译器检查签名是否与父类的虚函数完全匹配,并且该函数确实重写了父类。如果不匹配,则编译过程会因错误而中断。
代码示例:
struct Base { virtual void foo() const {} }; struct Derived : Base { void foo() const override { /* 实现 */ } };
如果在‘Derived’中写成‘void foo()’而没有‘const override’,编译器将会报错。
主要特点:
可以只保留带有‘override’关键字的虚函数,而没有关键字‘virtual’吗?
可以,‘override’隐含函数是虚拟的。将‘virtual’与‘override’一起指定是多余的,但没有禁止。
如果函数只因为const或引用限定符(例如,&或&&)的修饰符不同,是否可能会出错?
是的,签名中的任何差异,包括const/引用,会破坏重写。例如,‘void foo() override’不会重写‘void foo() const’,编译器会通过‘override’捕获这一点。
可以将‘override’应用于静态函数或构造函数吗?
不可以。‘override’仅适用于虚函数,不能应用于静态函数、构造函数、析构函数(如果它们不是虚拟的)。
在一个大型项目中,继承类的函数签名存在拼写错误:该函数实际上并没有重写,但开发者认为相反,多态性未按预期工作。
优点:
缺点:
在所有派生类中使用‘override’,测试在构建阶段捕获错误。
优点:
缺点: