Деструктор из взаимно рекурсивного класса с shared_from_this не вызывается

У меня есть два класса, A и B, у которых shared_ptr указывает друг на друга (у A есть shared_ptr для B, у B есть shared_ptr для A).

Я пытаюсь вызвать деструктор обоих классов при выходе из области видимости, но это не работает. Деструктор не вызывается.

Вот пример кода:

class B;

class A
{
    public:
        A() { std::cout << "Constructor A" << std::endl; }
        ~A() { std::cout << "Destructor A" << std::endl; }

        std::shared_ptr<B> b;
};

class B
{
    public:
        B() { std::cout << "Constructor B" << std::endl; }
        ~B() { std::cout << "Destructor B" << std::endl; }

        std::shared_ptr<A> a;
};

int main()
{
    std::shared_ptr<A> a = std::make_shared<A>();
    a->b = std::make_shared<B>();

    a->b->a = a;
}

Как я могу это исправить?


person Adrien Neveu    schedule 31.05.2016    source источник
comment
Звучит как ожидаемое поведение для меня, они никогда не выходят за рамки, поскольку они вечно ссылаются друг на друга.   -  person Callum Bradbury    schedule 31.05.2016
comment
это то, что weak_ptr для   -  person BeyelerStudios    schedule 31.05.2016


Ответы (1)


Удалите циклическую ссылку.

Объект, управляемый интеллектуальными указателями, уничтожается только тогда, когда последняя ссылка на объект выходит за пределы области видимости, при этом последний оставшийся общий указатель отвечает за deleteing и уничтожение объекта.

Ваш код устанавливает циклическую ссылку: пару объектов, которые указывают друг на друга с помощью интеллектуального указателя. Таким образом, всегда есть интеллектуальный указатель, который будет ссылаться на другой объект, при этом общий указатель каждого объекта предотвращает уничтожение другого объекта.

Пока эта циклическая ссылка не будет нарушена, эти объекты не будут уничтожены.

person Sam Varshavchik    schedule 31.05.2016