Sometimes I'm really sure that I want to have circular dependence of pointers, and every object on cycle should be able to use his pointer (so it can't be weak_ptr).
My question is: Does this mean that I have bad design?
What if I want to implement graph? Can I use smart pointers? In graphs there are cycles, but with weak_ptr I can't use "->". What can I do?
I read some articles, reference and topics on StackOverflow, but it looks like I still don't get smart pointers. Really, why doesn't exists some variant of weak_ptr with "->"?
As shown in the example, a smart pointer is a class template that you declare on the stack, and initialize by using a raw pointer that points to a heap-allocated object. After the smart pointer is initialized, it owns the raw pointer.
C++ libraries provide implementations of smart pointers in following types: auto_ptr.
Smart pointers perform automatic memory management by tracking references to the underlying object and then automatically deleting that object when the last smart pointer that refers to that object goes away.
C++11 comes up with its own mechanism that's Smart Pointer. When the object is destroyed it frees the memory as well. So, we don't need to delete it as Smart Pointer does will handle it.
Approach this from the conceptual side, not the implementation one. Smart pointers represent ownership. And existence of smart pointers does not invalidate the role of raw pointers as non-owning observers.
Does each object have a single, clearly defined owner (e.g. a graph owns all of its vertices and edges)? If so, use std::unique_ptr
to hold the vertices and edges in the graph, and use raw pointers inside vertices and edges to refer to each other.
Is shared ownership applicable (e.g. a vertex only exists as long as at least one edge is connected to it)? If so, use std::shared_ptr
to represent that ownership, again with raw pointers for non-owning observers. If you need mutual ownership (i.e. ownership cycles) where "a vertex only exists as long as an edge refers to it, and an edge only exists as long as a vertex refers to it," then 1. double-check that such design is correct and maintainable, and 2. if so, use a std::weak_ptr
somewhere in the cycle to break the ownership loop. You can always lock()
a weak_ptr
to obtain a shared_ptr
.
For your particular graph scenario, I believe "everything's owned by the graph" would be the most logical ownership scheme; but that depends on the idiosyncracies of your task.
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