我原以为如果在编译时已知类的类型(例如,如果类实例未通过引用或指针使用,如下面的Case 1),那么编译器就能够静态解析对虚函数的函数调用。
然而,我注意到使用Visual Studio 2010的C++编译器存在奇怪的行为,并想知道是否有任何理由使编译器不能将对“正确”虚函数的调用静态绑定,即当具有虚函数的类的实例是由引用访问的结构体成员时。
我应该期望编译器在下面的Case 2中将调用静态绑定到f()吗? 即使a是A而不是A&,cr的“引用性”是否会以某种方式传播到cr.a?
struct A
{
virtual void f() ;
virtual ~A() ;
};
struct B : A
{
virtual void f() ;
virtual ~B() ;
};
struct C {
A a ;
B b ;
};
C & GetACRef() ;
void test()
{
// Case 1) The following calls to f() are statically bound i.e.
// f() is called without looking up the virtual function ptr.
C c ;
c.a.f() ;
c.b.f() ;
A a ;
a.f() ;
// Case 2) The following calls to f() go through the dynamic dispatching
// virtual function lookup code. You can check if you generate the .asm
// for this file.
C & cr = GetACRef() ; // Note that C is not polymorphic
cr.a.f() ; // visual C++ 2010 generates call to f using virtual dispatching
cr.b.f() ; // visual C++ 2010 generates call to f using virtual dispatching
}
B::f
标记为final,则它成功地优化了cr.b.f()
) - Matthieu M.