The final example at page 137 of Effective Modern C++ draws the scenario of a data structure with objects A
, B
, and C
in it, connected to each other via std::shared_ptr
in the following way:
std::shared_ptr std::shared_ptr
A ─────────────────▶ B ◀───────────────── C
To me, this implies that the classes which objects A
and C
are instance of (two unrelated classes, in general) must contain a std::shared_ptr<classOfB>
member.
Then the supposition is made that we need a pointer from B
back to A
, and the available options are listed: the pointer can be raw, shared, or weak, and the last one is picked up as the best candidate.
std::shared_ptr std::shared_ptr
A ─────────────────▶ B ◀───────────────── C
▲ │
│ std::weak_ptr │
└────────────────────┘
I do understand the weaknesses (ahahah) of the first two alternatives, but I also see that the third alternative requires that member A
be already managed by some std::shared_ptr
, otherwise how can a std::weak_ptr
point to it at all?
However the book does not refer to this "limitation"/assumption/whatever, so the truth is either
std::weak_ptr
needs an already existing std::shared_ptr
to the same object, but it's a bit strange it's not even mentioned at the beginning of the example, I think.and I'm asking this question to understand this.
The only difference between weak_ptr and shared_ptr is that the weak_ptr allows the reference counter object to be kept after the actual object was freed. As a result, if you keep a lot of shared_ptr in a std::set the actual objects will occupy a lot of memory if they are big enough.
Note that the control block used by std::weak_ptr and std::shared_ptr is thread-safe: different non-atomic std::weak_ptr objects can be accessed using mutable operations, such as operator= or reset , simultaneously by multiple threads, even when these instances are copies or otherwise share the same control block ...
The shared_ptr type is a smart pointer in the C++ standard library that is designed for scenarios in which more than one owner might have to manage the lifetime of the object in memory.
"Shared pointer is a smart pointer (a C++ object wih overloaded operator*() and operator->()) that keeps a pointer to an object and a pointer to a shared reference count. Every time a copy of the smart pointer is made using the copy constructor, the reference count is incremented.
You're right, and your third bullet point is correct. A std::weak_ptr
always refers to an existing std::shared_ptr
. So, it is once we've made the decision that A is going to contain
a shared_ptr<BClass>
and that the instances of A are being managed as shared_ptr<AClass>
's that we can use a weak_ptr<AClass>
for the back-reference from B to A.
In a typical use case, you could have a D-class that manages three members shared_ptr<AClass> a;
, shared_ptr<BClass> b;
and shared_ptr<CClass> c;
, and then some member function in D-class does a->SetB(b);
, c->SetB(b);
, b->SetA(a);
, with the SetB member functions using shared_ptr's and SetA using a weak_ptr (or converting to weak_ptr within the member function). As you rightly say, if D did store the reference to A in any other way like, say, a raw pointer AClass* a;
or an instance AClass a;
, then using a weak_ptr would simply not be possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With