编译器添加的优化会导致"最终"方法的不同行为

iam*_*ind 2 c++ optimization final c++11

struct B { 
  virtual void foo ()
  { cout << "B::foo()\n"; }
};

struct D : B { 
  void foo () //final
  { cout << "D::foo()\n"; }
};

int main ()
{
  B *pB = new B;
  D *pD = static_cast<D*>(pB);
  pB->foo();
  pD->foo();
}
Run Code Online (Sandbox Code Playgroud)

输出预期行为:

B::foo()
B::foo()
Run Code Online (Sandbox Code Playgroud)

如果我们做出D::foo()决赛,那么输出就会大不相同:

B::foo()
D::foo()
Run Code Online (Sandbox Code Playgroud)

这意味着virtual当使用声明该方法的类的指针/引用调用方法时,不会启用该功能final.
这也意味着,它final不仅仅是一个编译时检查,而且还有助于运行时行为.

它是所有编译器的标准行为.我用g ++ 4.7测试过.

编辑:
产生了一个澄清的新问题.结束这个问题.

Nic*_*las 11

D *pD = static_cast<D*>(pB);
Run Code Online (Sandbox Code Playgroud)

通过此声明,您放弃了理解程序行为的权利.如果给定的内容实际上不是类型或者派生类之一(它不是),则C++ 不需要此操作.static_castDD

因此,不是优化会阻碍你,只是糟糕的代码.

存在的原因dynamic_cast是什么; 一个专业dynamic_cast人士很快就会失败,返回nullptr非法演员.


Xeo*_*Xeo 5

您正在进入未定义行为的领域,因为您通过指针/引用访问对象的类型不是对象的实际类型.

3.10 [basic.lval] p10

如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:

  • 对象的动态类型
  • [...]

动态型的pBBase*,很明显,但动态类型pD依旧 Base*.