Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11: Replace all non-owning raw pointers with std::shared_ptr()?

With the advent of std::unique_ptr, the blemished std::auto_ptr can finally be put to rest. So for the last several days, I have been changing my code to use smart pointers and to eliminate all delete from my code.

Although valgrind says my code is memory-clean, the semantic richness of smart pointers will make for cleaner and easier-to-understand code.

In most of the code, the translation is simple: use std::unique_ptr for in place of the raw pointers held by the owning objects, throw out delete, and carefully sprinkle get(), reset() and move() calls, as needed, to interface well with the rest of the code.

I am at the point where I am translating non-owning raw pointers to smart pointers now.

Since I was careful with the lifetimes of my objects (I ensure my modules only depend in one direction), valgrind tells me that I don't have any uninitialized reads, dangling pointers, or leaks. So, technically, I could just leave those non-owning raw pointers alone now.

However, one option is to change those non-owning raw pointers to std::shared_ptr because I know they are acyclic. Or, would it be better to leave them as raw pointers?

I need some advice from veteran users of smart pointers as to what rules of thumb you use to decide whether to keep non-owning raw pointers as-is, or to translate them into std::shared_ptr, keeping in mind that I constantly unit-test and valgrind my code.

EDIT: I might be misunderstanding the use of std::shared_ptr - can they be used in conjunction with std::unique_ptr, or is it the case that if I use std::shared_ptr, all handles should also be std::shared_ptr?

like image 866
kfmfe04 Avatar asked Dec 01 '11 08:12

kfmfe04


People also ask

What does shared_ptr get () do?

std::shared_ptr::getReturns the stored pointer. The stored pointer points to the object the shared_ptr object dereferences to, which is generally the same as its owned pointer.

Should I use shared_ptr or Unique_ptr?

Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.

When should you use shared_ptr?

So, we should use shared_ptr when we want to assign one raw pointer to multiple owners. // referring to the same managed object. When to use shared_ptr? Use shared_ptr if you want to share ownership of a resource.

What is a shared_ptr in C++?

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.


2 Answers

Use a shared_ptr when you require multiple things own a resource (and those owning things may go in and out of scope at "random"), use a unique_ptr when a single thing owns the resource, and use a raw pointer when you just need to refer to it and not own it (and expect this referral to not last longer than the resource exists).

There is a fourth type, a sort of raw-pointer-for-shared_ptr's, called weak_ptr. You use that to refer to a shared_ptr without actually owning it; you can then check if the object is still there and use it.

like image 44
GManNickG Avatar answered Sep 19 '22 17:09

GManNickG


Personally, this is how I (more or less) do it:

  • unique_ptrs are for sole ownership
  • raw pointers mean whoever gave me the raw pointer guarantees the lifetime of that object to match or exceed my lifetime.
  • shared_ptrs are for shared ownership
  • weak_ptrs are for when a system wants to check if the object still exists before using it. This is rare in my code since I find it cleaner to have a system guarantee the lifetime of anything it passes it's subsystems (in which case I use a raw pointer)

By far I use more unique_ptrs than shared_ptrs, and more raw pointers than weak pointers.

like image 186
David Avatar answered Sep 23 '22 17:09

David