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