#include <iostream>
class A
{
public:
virtual ~A() = default;
virtual void foo(void) = 0;
};
class B : public A
{
private:
int x;
public:
B(int a) : x(a) {}
void foo(void) { std::cout << "B: " << x << "\n"; }
};
class Foo
{
private:
A* a_ptr;
public:
Foo (B& x) { a_ptr = &x; }
A* get_ptr(void) { return a_ptr; }
void dummy(void) { std::cout << "Foo: "; std::cout << a_ptr << "\t "<< typeid(*a_ptr).name() << "\n"; a_ptr->foo(); std::cout << "\n"; }
};
int main(void)
{
B b(10);
Foo f(b);
f.dummy();
return 0;
}
Если конструктор Foo
принимает ссылку на объект B
, тогда эта программа выполняется так, как я ожидал, т.е. a_ptr->foo()
вызывает B::foo()
.
Однако, если конструктор изменяется так, чтобы параметр принимался по значению, то a_ptr->foo()
преобразуется в A::foo()
и приводит к pure virtual method called exception
Пример вывода (передан по ссылке :):
Foo: 0x7fffe90a24e0 1B
B: 10
Пример вывода (передан по значению):
Foo: 0x7fffc6bbab20 1A
pure virtual method called
terminate called without an active exception
Aborted (core dumped)
У меня смутное представление о том, почему это может происходить, и я ищу литературу или ссылку, которые могут доказать или опровергнуть мою гипотезу: при передаче по ссылке указатель базового класса a_ptr
указывает на сущность, время жизни которой превышает время обращения к a_ptr->foo()
.
Однако при передаче по значению a_ptr
указывает на временное, которое теряется при выходе из конструктора.
Я полагаю, это как-то связано с VTABLE
из A
, но я не могу понять это.