为什么不能在C ++ 11中将非虚方法定义为final?

时间:2014-07-03 05:38:54

标签: c++ c++11

今天,当我了解到C ++ 11现在终于知道final关键字时,我感到非常高兴。有了它,您可以轻松地将整个类定义为 final 甚至单个虚拟方法。但我想知道为什么非虚拟方法不可能这样做?让我们举个例子:

class A {
public:
    void m1() { cout << "A::m1" << endl; };            
    virtual void m2() { cout << "A::m2" << endl; };      
};

class B : public A {
public:
    void m1() { cout << "B::m1" << endl; };
    virtual void m2() { cout << "B::m2" << endl; };
};

通过将B声明为最终版,我可以轻松阻止m2覆盖虚拟A::m2。我想对A::m1做同样的事情,因此B无法隐藏A:m1自己的方法实现。但是编译器在没有final的情况下不接受virtual关键字。我想知道是否有理由说C ++ 11不允许这样做,如果我完全误解了一些东西。在我看来,将非虚拟方法定义为final是非常有意义的,因为我没有将其声明为虚拟,因为我不希望其他人覆盖/隐藏它(我现在可以使用{ {1}}但不幸的是只有虚拟方法......)

我喜欢类设计,除了抽象方法之外的所有东西都是最终的。看起来这意味着我必须将所有方法声明为final才能够做到这一点。这是一个好主意还是有理由反对它?对于较旧的C ++版本,我经常读到将所有方法声明为虚拟的一个坏主意。或者可能有更好的方法来防止隐藏非虚拟方法?

1 个答案:

答案 0 :(得分:5)

根据C ++ 11标准,您明确不允许对函数执行此操作。相关段落见§9.2/ 8:

  

virt-specifier-seq 最多应包含每个 virt-specifier 中的一个。 virt-specifier-seq 只能出现在虚拟成员函数的声明中(10.3)。

virt-specifier 包括finaloverride

我的猜测是他们认为这些说明符在非虚函数中没有意义,因为默认情况下非虚函数是final,它们是标准状态的“最终覆盖”在其他部分。

  

看起来这意味着我必须将所有方法声明为虚拟现在能够做到这一点。这是一个好主意还是有理由反对它?

我建议反对它 - 因为虚拟功能对你可能不想要的代码有不同的影响。例如,该类现在必须保留vtable并丢失其POD状态。总的来说,如果您只想使用final关键字,这似乎是一个不好的举动。