Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Smart pointers + cycles + "->"

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

like image 500
Krzysztof Stanisławek Avatar asked May 01 '14 13:05

Krzysztof Stanisławek


People also ask

How does a smart pointer work?

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.

What are the different types of smart pointers?

C++ libraries provide implementations of smart pointers in following types: auto_ptr.

Do smart pointers automatically delete?

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.

Is smart pointers C++11?

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.


1 Answers

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.

like image 145
Angew is no longer proud of SO Avatar answered Oct 08 '22 03:10

Angew is no longer proud of SO