隐式虚拟传播的原因是什么?

时间:2016-08-21 07:47:13

标签: c++ methods virtual propagation

我只使用C ++工作了2~3个月,最近我发现了虚拟功能之后的标识符 final 。直到今天,我相信遗漏虚拟会阻止虚拟传播,但我错了。它含蓄地传播。

我的问题是这个。为什么允许隐式传播?为什么虚拟的存在使虚拟功能成为虚拟 虚拟使功能不是虚拟的?在某些情况下是更好的吗?还是它,是在虚拟首次推出的那一天回来的?

根据Clifford's answer,甚至有一个编译器在没有虚拟时会产生警告。

why is the virtuality of methods implicitly propagated in c

我希望上面的链接可以回答我的问题,但事实并非如此。

------------加法-------------

有关于询问此功能是否有用的评论。 我认为虚函数上的 final 关键字是虚函数化的功能。该函数不能再被覆盖,因此派生类必须重新声明一个函数,无论它是否具有相同的名称。 如果 final 与devirtualization不同,请帮助我理解它。 如果最终没有什么不同,那么从最终引入的事实来看,虚拟化的有用性是不言而喻的。 我同意强制明确的虚拟会产生错误,但如果还有其他原因,我很好奇。

1 个答案:

答案 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 ++通常试图远离那些需要纪律才能做到正确的功能。