C++管理虚方法之override和final
override 和 final
override
虚方法对实现多态类层次结构很重要,让基类引用或指针能够根据指向的对象类型调用相应的方法,但虚方法也带来了一些编程陷阱。如,假设基类声明了一个虚方法,而您决定在派生类中提供不同的版本,这将覆盖旧版本。但如果特征不匹配,将隐藏而不是覆盖旧版本。
class Action
{
int a;
public:
Action(int i = 0) : a(i) {}
int val() const { return a; }
virtual void f(char ch) const { std::cout << val() << ch << "\n"; }
};
class Bingo : public Action
{
public:
Bingo(int i = 0) : Action(i) {}
virtual void f(char * ch) const { std::cout << val() << ch << "!\n"; }
};
由于类 Bingo 定义的是 f(char *ch) 而不是 f(char ch),将对 Bigno 对象隐藏 f(char ch),这导致程序不能使用类似于下面的代码:
Bingo b(10);
b.f('@'); // works for Action object, fails for Bingo object
在 C++ 11 中,可使用虚说明符 override 指出要覆盖一个虚函数:将其放在参数列表后面。如果声明与基类方法不匹配,编译器将视为错误。
因此,下面的 Bingo::f() 版本将生成一条编译错误信息:
virtual void f(char * ch) const override { std::cout << val() << ch << "!n"; }
如,在 Microsoft Visual C++ 2010 中,出现的错误信息如下:
method with override specifier 'override' did not override any basy class methods
final
若想禁止派生类覆盖特定的虚方法,为此可在参数列表后面加上 final。如,下面的代码禁止 Action 的派生类重新定义函数 f():
virtual void f(char ch) const final { std::cout << val() << ch << "\n!"; }
说明符 override 和 final 并非关键字,而是具有特殊含义的标识符。这意味着编译器根据上下文确定它们是否有特殊含义:在其他上下文中,可将它们用作常规标识符,如变量名或枚举。

浙公网安备 33010602011771号