Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why shouldn't I use shared_ptr and unique_ptr always and instead use normal pointers?

I have a background in C# and obj-c so RC/GC are things I (still) hold dear to me. As I started learning C++ in more depth, I can't stop wondering why I would use normal pointers when they are so unmanaged instead of other alternative solutions?

the shared_ptr provides a great way to store references and not lose track of them without deleting them. I can see practical approaches for normal pointers but they seem just bad practices.

Can someone make of case of these alternatives?

like image 409
Alex Avatar asked Dec 01 '13 17:12

Alex


4 Answers

Ofcourse you're encouraged to use shared and unique ptr IF they're owning pointers. If you only need an observer however, a raw pointer will do just fine (a pointer bearing no responsibility for whatever it points to).

There is basically no overhead for std::uniqe_ptr and there is some in std::shared_ptr as it does reference counting for you, but rarely will you ever need to save on execution time here.

Also, there is no need for "smart" pointers if you can guarantee lifetime / ownership hierarchy by design; say a parent node in a tree outliving its children - although this is slightly related to the fact whether the pointer actually owns something.

like image 123
ScarletAmaranth Avatar answered Nov 10 '22 01:11

ScarletAmaranth


As someone else mentioned, in C++ you have to consider ownership. That being said, the 3D networked multiplayer FPS I'm currently working on has an official rule called "No new or delete." It uses only shared and unique pointers for designating ownership, and raw pointers retrieved from them (using .get()) everywhere that we need to interact with C API's. The performance hit is not noticeable. I use this as an example to illustrate the negligible performance hit since games/simulations typically have the strictest performance requirements.

This has also significantly reduced the amount of time spent debugging and hunting down memory leaks. In theory, a well-designed application would never run into these problems. In real life working with deadlines, legacy systems, or existing game engines that were poorly designed, however, they are an inevitability on large projects like games... unless you use smart pointers. If you must dynamically allocate, don't have ample time for designing/rewriting the architecture or debugging problems related to resource management, and you want to get it off the ground as quickly as possible, smart pointers are the way to go and incur no noticeable performance cost even in large-scale games.

like image 25
derpface Avatar answered Nov 10 '22 00:11

derpface


The question is more the opposite: why should you use smart pointers? Unlike C# (and I think Obj-C), C++ makes extensive use of value semantics, which means that unless an object has an application specific lifetime (in which case, none of the smart pointers apply), you will normally be using value semantics, and no dynamic allocation. There are exceptions, but if you make it a point of thinking in terms of value semantics (e.g. like int), of defining appropriate copy constructors and assignment operators where necessary, and not allocating dynamically unless the object has an externally defined lifetime, you'll find that you rarely need to do anything more; everything just takes care of itself. Using smart pointers is very much the exception in most well written C++.

like image 23
James Kanze Avatar answered Nov 09 '22 23:11

James Kanze


Sometimes you need to interoperate with C APIs, in which case you'll need to use raw pointers for at least those parts of the code.

like image 44
Jim Lewis Avatar answered Nov 09 '22 23:11

Jim Lewis