Я ожидал, что компилятор сможет статически разрешить вызов функции виртуальной функции, если тип класса известен во время компиляции (например, если экземпляр класса не используется через ссылку или указатель, как показано в Случай 1) ниже).
Однако я наблюдал странное поведение с компилятором Visual Studio 2010 С++, и я хотел бы знать, есть ли какая-либо причина для компилятора не статически привязывать вызовы к "правильной" виртуальной функции, когда экземпляры классов с виртуальными функциями являются членами в структуре, к которой обращается ссылка.
Должен ли я ожидать, что компилятор будет статически привязывать вызовы к f() в примере 2) ниже? Является ли "ссылка" cr каким-то образом распространяться на cr.a, хотя a
является a
, а не 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
}