Ответ 1
О, это очень недействительно.
Рассмотрим:
#include <iostream>
using namespace std;
struct A {
virtual ~A() { cout << "~A" << endl; }
virtual void doit() const = 0;
};
struct B : public A
{
~B() override { cout << "~B" << endl; }
void doit() const override { cout << "A::doit" << endl; }
};
struct C : public A
{
~C() override { cout << "~C" << endl; }
virtual void doit() const { cout << "C::doit" << endl; }
};
void foo(bool p)
{
cout << "foo( " << p << ")" << endl;
const A &a = (p ? static_cast<const A &>(B()) : static_cast<const A &>(C()));
a.doit();
}
auto main( int argc, char* argv[] ) -> int
{
cout << boolalpha;
foo( true );
cout << endl;
foo( false );
}
Вывод в Coliru Viewer, используя g++ 4.8:
foo( true) ~B ~A pure virtual method called terminate called without an active exception bash: line 7: 16922 Aborted (core dumped) ./a.out
Это UB, поэтому любое объяснение может быть правдой, но можно быть достаточно уверенным, не глядя на сборку, что происходит:
- Создается временная структура.
- Он привязан к ссылке.
Это ссылка привязана к ссылке, поэтому не требуется создание нового временного или среза. - Временное уничтожается.
- В качестве части этого динамический тип (указатель vtable) изменяется на
A
, который является абстрактным. - Вызывается чистый виртуальный объект в
A
.