当前位置:嗨网首页>书籍在线阅读

23-管理虚方法_override和final

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

18.3.5 管理虚方法:override和final

虚方法对实现多态类层次结构很重要,让基类引用或指针能够根据指向的对象类型调用相应的方法,但虚方法也带来了一些编程陷阱。例如,假设基类声明了一个虚方法,而您决定在派生类中提供不同的版本,这将覆盖旧版本。但正如第13章讨论的,如果特征标不匹配,将隐藏而不是覆盖旧版本:

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),将对Bingo对象隐藏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
base class methods

说明符final解决了另一个问题。您可能想禁止派生类覆盖特定的虚方法,为此可在参数列表后面加上final。例如,下面的代码禁止Action的派生类重新定义函数f():

virtual void f(char ch) const final { std::cout << val() << ch << "\n";}

说明符override和final并非关键字,而是具有特殊含义的标识符。这意味着编译器根据上下文确定它们是否有特殊含义;在其他上下文中,可将它们用作常规标识符,如变量名或枚举。