[英]Recipe for `final`: omit `virtual`?
Is it a valid recipe to say that if I write final
(to a member function) one should not write virtual
? 这是一个有效的方法,如果我写
final
(成员函数),不应该写virtual
?
In a base class, final
methods would make no sense: 在基类中,
final
方法没有意义:
struct Driver {
virtual void print();
};
If one would add final
to print()
this would defy the reason for polymorphism in the first place. 如果要将
final
添加到print()
这将首先违反多态性的原因。 So that would be useless (though possible). 所以这将是无用的(虽然可能)。
When I derive from this class I can detect errors with final
, but only without virtual
: 当我从这个类派生时,我可以用
final
检测错误,但只有没有 virtual
:
struct KeyboardDriver : public Driver {
virtual void prynt() final; // Oops: typo, but compiler-ok
};
struct MouseDriver : public Driver {
void prynt() final; // Error: Hooray, compiler found my typo
};
The additional final
for KeyboardDriver::prynt
was legal. KeyboardDriver::prynt
的额外final
是合法的。 Because final
only requires the member function to be virtual
-- the compiler lets this pass (FDIS 9.2p9). 因为
final
只需要成员函数是virtual
- 编译器允许它通过(FDIS 9.2p9)。
But when I leave out the virtual
the typo makes this function non-virtual -- it overrides nothing, ie no virtual function. 但是当我忽略
virtual
,拼写错误使得这个函数非虚拟 - 它不会覆盖任何东西,即没有虚函数。 Therefore final
without virtual
serves the same purpose to this respect as override
does. 因此,没有
virtual
final
就像override
一样在这方面起到了相同的作用。
Update: Is my analysis correct? 更新: 我的分析是否正确? Does the functionality of
final
without virtual
include that one of override
? 没有
virtual
的final
的功能是否包含override
?
That is not what final
is for. 这不是
final
的结果。 What you are looking for is override
. 您正在寻找的是
override
。
struct Base {
virtual void print();
};
struct Derived : Base {
void prynt() override; //compiler error
};
struct Good : Base {
void print() override; //no compiler error
};
If you mark a function as override
when it does not, then you get an error. 如果将函数标记为
override
,则不会,则会出现错误。 Combined with your final function, you get all the comforts of compiler checked safety, with the clarity of explicitly marking functions virtual
when coding standards demand it. 与您的最终功能相结合,你的编译器的所有舒适安全检查,以明确地标记功能清晰度
virtual
时编码标准所要求的。
struct Best : Base {
virtual void print() final override;
};
Your analysis is correct. 你的分析是正确的。 Not marking a
final
member as virtual
avoids declaring a new, non-overriden member and catches mistakes. 不将
final
成员标记为virtual
成员可以避免声明新的非重写成员并捕获错误。 However, since that's the purpose of override
, it may be simpler to just use final override
; 但是,由于这是
override
的目的,因此使用final override
可能更简单; then whether the member is marked virtual
or not won't matter at all. 那么该成员是否被标记为
virtual
将无关紧要。
I do not think it is an error, it's just a virtual function that can not be overloaded. 我不认为这是一个错误,它只是一个无法重载的虚函数。 Same thing that would happen if the function were declared virtual in a parent class, since virtual declarations are inherited.
如果函数在父类中声明为虚拟,则会发生同样的事情,因为虚拟声明是继承的。 It would make no sense to forbid it.
禁止它是没有意义的。
Is my analysis correct?
我的分析是否正确? Does the functionality of final without virtual include that one of override?
没有虚拟的final的功能是否包含覆盖的功能?
No. The reason that this was a compiler error: 不。这是编译器错误的原因:
void prynt() final; // Error: Hooray, compiler found my typo
Is because final
is only allowed on virtual functions. 是因为
final
只允许在虚函数上使用。 The compiler is complaining because you used it on a function that isn't virtual. 编译器抱怨,因为你在一个非虚拟的函数上使用它。
There is nothing syntactically wrong about this line: 这条线在语法上没有任何错误:
virtual void prynt() final; // Oops: typo, but compiler-ok
It may not be what you want, but this is legitimate (and even meaningful, depending on the circumstances) code. 它可能不是你想要的,但这是合法的(甚至是有意义的,取决于具体情况)代码。
The problem you are encountering is due to wanting to do this: 您遇到的问题是由于想要这样做:
struct Driver {
virtual void print();
};
struct MouseDriver : public Driver {
void print();
};
Omitting the virtual
is technically legal. 省略
virtual
技术在技术上是合法的。 But personally, I've always felt that it was bad form. 但就个人而言,我一直觉得这是糟糕的形式。 You're putting vital information (which functions are overridden) into another class.
您将重要信息(被覆盖的功能)放入另一个类中。 I think it was a mistake to even allow this to compile.
我认为甚至允许这个编译是错误的。
If you want to avoid this problem, then explicitly state virtual
on all virtual functions, and use override
in the places where you mean to create a new function. 如果要避免此问题,请在所有虚函数上显式声明
virtual
,并在创建新函数的位置使用override
。 Then, this will fail to compile correctly. 然后,这将无法正确编译。
struct Driver {
virtual void print();
};
struct MouseDriver : public Driver {
virtual void print() override;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.