为什么“override/final”需要放在函数声明后面?

7

我一直想知道这个决定的原因,为什么overridefinal必须在成员函数声明符之后:

struct Base {
    virtual void virtFun();
};
struct Foo: Base {
    virtual void virtFun() override;
};

对我来说,更合理的做法是在override/final的位置放置virtual

struct Base {
    virtual void virtFun();
};
struct Foo: Base {
    override void virtFun();
};

这是有原因的吗?也许与 C++11 之前的兼容性有关?


你也可以写成virtual void virtFun() override - Justin
2
为什么override和final标识符具有特殊含义而不是保留关键字?密切相关... override和final最终被用于语法中用户标识符无法出现的地方。因此,在这些地方,标识符可以具有特殊含义,并且在上下文之外,它们可以被视为常规标识符,从而使标识符可供用户使用。 - Shafik Yaghmour
1
@ShafikYaghmour 简而言之,这基本上是一种技巧,用于保持与 C++11 之前的代码兼容性,就像 op 猜测的那样。因此,语言语法变得比以前更不一致了。我认为更好的想法是要求编译器在某个标识符和“specifies”之间发生名称冲突时发出警告,然后将这些“specifiers”作为适当的保留关键字。 - user7860670
1
一个合适的术语是“上下文关键字”,它只有在正确的位置出现时才有意义。编译器只有在足够了解语句上下文时才会特殊处理它。将其放在语句末尾会产生很大的差异,解析器已经非常清楚你正在编写一个函数声明,因此不需要关键字提供的帮助。与经历同样演变的Java相比,他们必须写@Override。那个@符号很丑陋,但确实允许它出现在声明的开头。 - Hans Passant
@HansPassant: 是的,@符号很丑陋。我的解决方案是禁止将overridefinal用作类型名称。这些本来就不太可能是类型名称。正因为如此,我们把这些限定词放错了位置。使用override/final作为类型名称的好处远远低于允许将其放在正确的位置上的好处。我们很少(几乎从不)将override/final用作类型名称,而是经常将它们用于指定重写/最终方法。 - geza
显示剩余4条评论
1个回答

18

这是因为overridefinal不是关键字,而是特殊的标识符

这意味着您实际上可以使用这些名称声明变量、函数或类型名称(类型别名或类)。

它们只能像成员函数修饰符一样在非常小的上下文中使用,在编译器解析源代码时必须预先知道上下文。将它们放在函数声明之后是从C++语法中非常简单的方式,用于清除该上下文中的歧义。


2
这意味着如果它们位于“virtual”的位置,您可能会遇到一些问题:final myFunction();是返回final数据类型的函数。至少,在该位置允许使用final/override将使语法复杂化,但可能会产生歧义。 - Justin
谢谢你的回答!但是,它们可能是虚拟位置的特殊标识符,不是吗?在那里,只能是类型,这似乎并不难。有了这个,变量、函数仍然可以用这些名称指定,只是类型不能。 - geza
@geza 问题在于这些名称也可能被用作类型名称。你甚至可以定义一个名为 override 的类。禁止某些标识符用于特定类别是非常棘手的问题,会引发无穷无尽的连锁反应。 - Some programmer dude
好的 :) overridefinal 不太可能是类型名称。对我而言,使用override/final代替virtual所带来的好处要高得多,以至于我无法将它们用作类型名称。不过现在我理解了背后的决策,但我并不同意。 - geza
@geza 引入新关键词可能会破坏许多现有代码(因此在标准化过程中是一个非常高的障碍)。 这是一个妥协。 如果将它们添加为关键字,则具有overridefinal的任何现有程序都无法编译,并且更改提议者必须“成本证明”潜在的破坏性变化以符合标准。 - Richard Critten
@RichardCritten:是的,我明白了。我不是在谈论关键字,它本来可以只是保留的类型名称。我知道这可能会破坏现有的代码,但并不会太多。而且,在很多情况下修复它们应该很容易。而且创建新的关键字也不是被禁止的,constexpr就是一个新的关键字。是的,constexpr不太可能引起太多麻烦,但是禁止将final/override用作类型名称也不应该引起太多麻烦。无论如何,决定已经做出,争论这个问题没有太大意义。 - geza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接