C++ override specifier [C++ override 说明符]
- 1. C++ override specifier
- 2. C++ override 说明符
- 3. Compiler Error C2723
- References
在派生类中用 override
修饰符定义虚函数时,编译器会验证直接或间接基类是否包含签名相同的虚函数。如果不包含,就生成一个错误消息。
1. C++ override specifier
C++ documentation (C++ 文档)
https://learn.microsoft.com/en-us/cpp/cpp/
https://learn.microsoft.com/zh-cn/cpp/cpp/
override specifier (override 说明符)
https://learn.microsoft.com/en-us/cpp/cpp/override-specifier
https://learn.microsoft.com/zh-cn/cpp/cpp/override-specifier
You can use the override
specifier to designate member functions that override
a virtual
function in a base class.
可以使用 override
说明符来指定覆盖基类中的虚成员函数。
override
is context-sensitive and has special meaning only when it’s used after a member function declaration; otherwise, it’s not a reserved keyword.
override
是上下文相关的,只有在成员函数声明后使用时才具有特殊含义;否则,它不是保留关键字。
Use override
to help prevent inadvertent inheritance behavior in your code. The following example shows where, without using override
, the member function behavior of the derived class may not have been intended. The compiler doesn’t emit any errors for this code.
使用 override
有助于防止你的代码中出现意外的继承行为。以下示例演示在未使用 override
的情况下,可能不打算使用派生类的成员函数行为。编译器不会发出此代码的任何错误。
class BaseClass {
virtual void funcA();
virtual void funcB() const;
virtual void funcC(int = 0);
void funcD();
};
class DerivedClass : public BaseClass {
virtual void funcA(); // Works as intended
// DerivedClass::funcB() is non-const, so it does not override BaseClass::funcB() const
// and it is a new member function
virtual void funcB();
// DerivedClass::funcC(double) has a different parameter type than BaseClass::funcC(int),
// so DerivedClass::funcC(double) is a new member function
virtual void funcC(double = 0.0);
};
When you use override
, the compiler generates errors instead of silently creating new member functions.
当使用 override
时,编译器会生成错误,而不会在不提示的情况下创建新的成员函数。
class BaseClass {
virtual void funcA();
virtual void funcB() const;
virtual void funcC(int = 0);
void funcD();
};
class DerivedClass : public BaseClass {
virtual void funcA() override; // ok
// Compiler error: DerivedClass::funcB() does not override BaseClass::funcB() const
virtual void funcB() override;
// Compiler error: DerivedClass::funcC(double) does not override BaseClass::funcC(int)
virtual void funcC(double = 0.0) override;
// Compiler error: DerivedClass::funcD() does not override the non-virtual BaseClass::funcD()
void funcD() override;
};
To specify that functions cannot be overridden and that classes cannot be inherited, use the final
specifier.
若要指定不能重写函数且不能继承类,请使用 final
说明符。
2. C++ override 说明符
派生类如果定义了一个函数与基类中虚函数的名字相同但是形参列表不同,这仍然是合法的行为。编译器将认为新定义的这个函数与基类中原有的函数是相互独立的,派生类的函数并没有覆盖掉基类中的版本。就实际的编程习惯而言,这种声明往往意味着发生了错误,因为我们可能原本希望派生类能覆盖掉基类中的虚函数,但是一不小心把形参列表弄错了。
在 C++11 新标准中我们可以使用 override
修饰符来说明派生类中的虚函数。如果我们使用 override
标记了某个函数,但该函数并没有覆盖已存在的虚函数,此时编译器将报错。
struct B {
virtual void f1(int) const;
virtual void f2();
void f3();
};
struct D1 : B {
void f1(int) const override; // 正确:f1 与基类中的 f1 匹配
void f2(int) override; // 错误:B 没有 void f2(int) 形式的函数
void f3() override; // 错误:f3 不是虚函数
void f4() override; // 错误:B 没有名为 f4 的函数
};
在 D1
中,f1
的 override
说明符是正确的,因为基类和派生类中的 f1
都是 const
成员,并且它们都接受一个 int
并返回 void
,所以 D1
中的 f1
正确地覆盖了它从 B
中继承而来的虚函数。
D1
中 f2
的声明与 B
中 f2
的声明不匹配,显然 B
中定义的 f2
不接受任何参数而 D1
的 f2
接受一个 int
。因为这两个声明不匹配,所以 D1
的 f2
不能覆盖 B
的 f2
,它是一个新函数,仅仅是名字恰好与原来的函数一样而已。因为我们使用 override
所表达的意思是我们希望能覆盖基类中的虚函数而实际上并未做到,所以编译器会报错。
因为只有虚函数才能被覆盖,所以编译器会拒绝 D1
的 f3
。该函数不是 B
中的虚函数,因此它不能被覆盖。类似的,f4
的声明也会发生错误,因为 B
中根本就没有名为 f4
的函数。
3. Compiler Error C2723
‘function’ : ‘specifier’ specifier illegal on function definition
error C2723: '***': 'override' specifier illegal on function definition
'override' specifier is not allowed outside a class definition
The specifier cannot appear with a function definition outside of a class declaration. The virtual
specifier can be specified only on a member function declaration within a class declaration.
说明符不能与类声明外部的函数定义同时出现,仅能对类声明内的成员函数声明指定 virtual
说明符。
References
[1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/
[2] C++ final specifier 禁止派生类和禁止重写函数, https://blog.csdn.net/chengyq116/article/details/104477726