如果我编写final
(对成员函数),就不应该编写virtual
,这是否是一个有效的秘诀?
在基类中, final
方法毫无意义:
struct Driver {
virtual void print();
};
如果将 final
添加到 print()
中,这首先就会违背多态性的原因。所以这将是无用的(尽管可能)。
当我从此类派生时,我可以检测到有 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
};
附加的 KeyboardDriver::prynt
的 >final 是合法的。因为final
只要求成员函数是virtual
——编译器会让这个通过(FDIS 9.2p9)。
但是,当我省略virtual
时,拼写错误使该函数成为非虚拟函数——它不会覆盖任何内容,即没有虚拟函数。因此,没有virtual
的final
在这方面与override
具有相同的目的。
更新:我的分析正确吗?没有 virtual
的 final
功能是否包括 override
之一?
Is it a valid recipe to say that if I write final
(to a member function) one should not write virtual
?
In a base class, final
methods would make no sense:
struct Driver {
virtual void print();
};
If one would add final
to print()
this would defy the reason for polymorphism in the first place. So that would be useless (though possible).
When I derive from this class I can detect errors with final
, but only without 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. Because final
only requires the member function to be virtual
-- the compiler lets this pass (FDIS 9.2p9).
But when I leave out the virtual
the typo makes this function non-virtual -- it overrides nothing, i.e. no virtual function. Therefore final
without virtual
serves the same purpose to this respect as override
does.
Update: Is my analysis correct? Does the functionality of final
without virtual
include that one of override
?
发布评论
评论(4)
你的分析是正确的。不将
final
成员标记为virtual
可以避免声明新的、不可重写的成员并捕获错误。但是,由于这就是override
的目的,因此使用final override
可能会更简单;那么该成员是否被标记为virtual
根本不重要。Your analysis is correct. Not marking a
final
member asvirtual
avoids declaring a new, non-overriden member and catches mistakes. However, since that's the purpose ofoverride
, it may be simpler to just usefinal override
; then whether the member is markedvirtual
or not won't matter at all.这不是
final
的用途。您正在寻找的是覆盖
。如果您将某个函数标记为
override
,但实际上它没有,则会出现错误。与您的最终函数相结合,您可以获得编译器检查安全性的所有便利,并且在编码标准需要时可以清楚地显式标记函数virtual
。That is not what
final
is for. What you are looking for isoverride
.If you mark a function as
override
when it does not, then you get an error. Combined with your final function, you get all the comforts of compiler checked safety, with the clarity of explicitly marking functionsvirtual
when coding standards demand it.我不认为这是一个错误,它只是一个不能重载的虚函数。如果该函数在父类中声明为 virtual ,也会发生同样的情况,因为 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.
不。这是编译器错误的原因:
因为
final
只允许在虚拟函数上使用。编译器会抱怨,因为您在非虚拟函数上使用了它。这行代码在语法上没有任何错误:
它可能不是您想要的,但这是合法的(甚至是有意义的,取决于具体情况)代码。
您遇到的问题是由于想要执行此操作:
省略
virtual
在技术上是合法的。但就我个人而言,我一直觉得这种形式很糟糕。您将重要信息(哪些函数被覆盖)放入另一个类中。我认为允许它编译是一个错误。如果您想避免此问题,请在所有个虚拟函数上显式声明
virtual
,并在您想要创建虚拟函数的地方使用override
新功能。那么,这将无法正确编译。No. The reason that this was a compiler error:
Is because
final
is only allowed on virtual functions. The compiler is complaining because you used it on a function that isn't virtual.There is nothing syntactically wrong about this line:
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:
Omitting the
virtual
is technically legal. 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 useoverride
in the places where you mean to create a new function. Then, this will fail to compile correctly.