Внутри D::operator std::shared_ptr<B>()
использование std::static_pointer_cast<B>(pb)
является неопределенным поведением , потому что pb
не указывает на экземпляр B
в этой точке, поэтому запрещается разыгрыватьA
указатель на B
указатель и доступ к B
членам. pb
указывает на экземпляр A
, созданный std::make_shared<A>()
в D::operator std::shared_ptr<A>()
. В операторе pb = *this;
вы отбрасываете созданный вами объект B
и становитесь владельцем объекта A
, возвращаемого *this
.
Таким образом, внутри main()
, pB
заканчиваетсяуказывает на недопустимый объект B
и пытается уничтожить этот объект при выходе из main()
, поэтому вы в конечном итоге разбили деструктор A
.
Если бы вы использовали dynamic_pointer_cast
вместо static_pointer_cast
внутри D::operator std::shared_ptr<B>()
вы бы получили нулевой указатель и, скорее всего, потерпели бы крах внутри D::operator std::shared_ptr<B>()
при доступе к B::b
вместо сбоя main()
.
Вам нужно исправить operator std::shared_ptr<B>()
для работы с действительным экземпляром B
, а не с экземпляром A
. Например:
operator std::shared_ptr<B>()
{
std::shared_ptr<B> pb = std::make_shared<B>();
std::shared_ptr<A> pa = *this;
*static_pointer_cast<A>(pb) = *pa; // <-- copy pa->a to pb->a ...
// or: simply do this instead:
// pb->a = pa->a;
pb->b = this->x;
return pb;
}