Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding of Scott Meyers' third example of std::weak_ptr

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

  • I'm wrong
  • I'm right but that assumption is obvious for some reason I don't understand
  • The assumption is obvious for the exact reason that a 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.

like image 221
Enlico Avatar asked Nov 19 '20 08:11

Enlico


People also ask

What is the difference between shared_ptr and Weak_ptr?

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.

Is std :: Weak_ptr thread safe?

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 ...

What is shared pointer in C++ example?

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.

How do shared pointers Work C++?

"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.


1 Answers

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.

like image 194
Ángel José Riesgo Avatar answered Nov 14 '22 21:11

Ángel José Riesgo