今天,当我了解到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 ++版本,我经常读到将所有方法声明为虚拟的一个坏主意。或者可能有更好的方法来防止隐藏非虚拟方法?
答案 0 :(得分:5)
根据C ++ 11标准,您明确不允许对函数执行此操作。相关段落见§9.2/ 8:
virt-specifier-seq 最多应包含每个 virt-specifier 中的一个。 virt-specifier-seq 只能出现在虚拟成员函数的声明中(10.3)。
virt-specifier 包括final
和override
。
我的猜测是他们认为这些说明符在非虚函数中没有意义,因为默认情况下非虚函数是final
,它们是标准状态的“最终覆盖”在其他部分。
看起来这意味着我必须将所有方法声明为虚拟现在能够做到这一点。这是一个好主意还是有理由反对它?
我建议反对它 - 因为虚拟功能对你可能不想要的代码有不同的影响。例如,该类现在必须保留vtable并丢失其POD状态。总的来说,如果您只想使用final
关键字,这似乎是一个不好的举动。