我只使用C ++工作了2~3个月,最近我发现了虚拟功能之后的标识符 final 。直到今天,我相信遗漏虚拟会阻止虚拟传播,但我错了。它含蓄地传播。
我的问题是这个。为什么允许隐式传播?为什么虚拟的存在使虚拟功能成为虚拟
根据Clifford's answer,甚至有一个编译器在没有虚拟时会产生警告。
why is the virtuality of methods implicitly propagated in c
我希望上面的链接可以回答我的问题,但事实并非如此。
------------加法-------------
有关于询问此功能是否有用的评论。 我认为虚函数上的 final 关键字是虚函数化的功能。该函数不能再被覆盖,因此派生类必须重新声明一个函数,无论它是否具有相同的名称。 如果 final 与devirtualization不同,请帮助我理解它。 如果最终没有什么不同,那么从最终引入的事实来看,虚拟化的有用性是不言而喻的。 我同意强制明确的虚拟会产生错误,但如果还有其他原因,我很好奇。
答案 0 :(得分:8)
为什么特定功能存在(或不存在)的答案通常相当困难,因为它成为猜测和意见的问题。但是,简单的答案可能是principle of least astonishment。提出一个有意义且可靠地运作并且可预测的计划将是困难的。
“虚拟化”功能甚至意味着什么?如果在运行时,您在对象上调用“devirtualized”函数,它是否会使用指针的静态类型?如果静态类型具有虚函数但运行时类型没有,那么会发生什么?
#include <iostream>
struct A { virtual void f() const { std::cout << "A"; } };
struct B : A { void f() const { std::cout << "B"; } };
struct C : B { virtual void f() const { std::cout << "C"; } };
struct D : C { void f() const { std::cout << "D"; } };
void f(const A& o) { o.f(); }
int main()
{
// "devirtualized" real C++
f(A{}); // "A" "A"
f(B{}); // "A" or "B"? "B"
f(C{}); // "C"? "C"
f(D{}); // oh god "D"
}
还有一个事实是,对于绝大多数设计,虚拟函数具有以在整个层次结构中保持虚拟。要求virtual
所有这些都会引入各种很难诊断的错误。 C ++通常试图远离那些需要纪律才能做到正确的功能。