Taking a look at std::weak_ptr
I have seen in a couple of places that it can be used to break memory leaks due to circular dependencies using std::shared_ptr
. See for example these two accepted answers: [1], [2].
Taking the last referenced answer, the proposed fix is:
#include <memory>
#include <iostream>
struct B;
struct A {
std::shared_ptr<B> b;
~A() { std::cout << "~A()\n"; }
};
struct B {
std::weak_ptr<A> a;
~B() { std::cout << "~B()\n"; }
};
void useAnB() {
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
a->b = b;
b->a = a;
}
int main() {
useAnB();
std::cout << "Finished using A and B\n";
}
This feels like an overkill, though, why not simply use a reference? I understand that in this example b->a
is not set in the constructor so a reference would not really cut it, so my question is:
Is there a reason to use a
std::weak_ptr
instead of a reference if the point is to break circular dependency if we can set it in the constructor?
NOTE: I understand the usefulness of std::weak_ptr
to hold a reference that can be invalidated. My question only concerns the usefulness when the point is exclusively to break circular dependency.
Here's a slightly modified function:
void useAnB() {
std::shared_ptr<B> oops;
{
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
a->b = b;
b->a = a;
oops = b;
}
// use oops->a
}
How could you know that oops->a
no longer refers to a valid object if it was a plain pointer or reference?