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

StackOverflow https://stackoverflow.com/questions/20315250

  •  07-08-2022
  •  | 
  •  

Вопрос

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?

Это было полезно?

Решение 2

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.

Другие советы

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.

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

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.

In embedded systems, pointers are often used to access registers of hardware chips or memory at specific addresses.

Since the hardware registers already exist, there is no need to dynamically allocate them. There won't be any memory leaks if the pointer is deleted or its value changed.

Similarly with function pointers. Functions are not dynamically allocated and they have "fixed" addresses. Reassigning a function pointer or deleting one will not cause a memory leak.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top