Problem
The following code shows the problem of a cyclic reference with shared pointers. When leaving the main function the strong reference counters for A and B gets reduced by one. But because they still have a strong reference to each other that counters are not reaching zero. This means none of both destructors will be called.
#include <iostream>
#include <memory>
class B;
class A
{
public:
void setup(std::shared_ptr<B> b) { m_b = b;}
~A() { std::cout << "destr. A" << std::endl; }
private:
std::shared_ptr<B> m_b;
};
class B
{
public:
void setup(std::shared_ptr<A> a) { m_a = a; }
~B() { std::cout << "destr. B" << std::endl; }
private:
std::shared_ptr<A> m_a;
};
int main()
{
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
a->setup(b);
b->setup(a);
return 0;
}
Solution
The following modification isn’t creating a cyclic reference anymore. When leaving the main function the strong reference counter of A will reach zero this time, cause B has just a weak_ptr on it. As soon as A gets destructed the strong reference counter of B reaches also zero and B will be destructed as well.
class B
{
public:
void setup(std::weak_ptr<A> a) { m_a = a; }
~B() { std::cout << "destr. B" << std::endl; }
private:
std::weak_ptr<A> m_a;
};