6

I have a question about smart pointers in c++ 11. I've started to have a look at C++ 11 (I usualy program in c#) and read some thing about smart pointers. Now i have the question, does smart pointers completely replace the "old" style of pointers, should i always use them?

The unique_ptr seems to solve all problems with memory management in C++, or am i wrong?

For example:

std::unique_ptr<GameManager> game (new GameManager());

game->Start();

Seems to be much smarter than:

auto *game2 = new GameManager();

game2->Start();

delete game2;

Thank you, i am a little bit confused!

BendEg
  • 16,106
  • 13
  • 46
  • 107
  • 6
    You should not use them when there is no question about ownership. For example, if something owns the game manager, and something else wants to use it (e.g. polymorphiclly) and has no say in its ownership or lifetime, then you could consider passing a raw pointer to it. – juanchopanza Sep 27 '14 at 16:53
  • Thank you, now it's more clearer – BendEg Sep 27 '14 at 16:59
  • 5
    "solve all problems" - no. It solves a great deal, though. – Mike Seymour Sep 27 '14 at 17:32
  • 2
    As frequently as not though, there's no need to use dynamic memory at all in C++. Unlike C#, C++ let's you create class instances on the stack, and they are destroyed when their containing scope exits. – Rob K Oct 01 '14 at 17:43
  • Possible duplicate http://stackoverflow.com/questions/20315250/why-shouldnt-i-use-shared-ptr-and-unique-ptr-always-and-instead-use-normal-poin/20315437 – derpface Oct 01 '14 at 19:14
  • @RobK there is a need, especially for dealing with relationship between different individuals(such as Parent, Child); and for Pimpl idiom it must use pointers. However i agree explicit dynamically allocated memory should be avoided as much as possible. – Hongxu Chen Oct 02 '14 at 01:40
  • Would be even smarter to use automatic variable rather than dynamic variable given the choice. `GameManager game2; game2.Start();` – Martin York Oct 02 '14 at 10:14
  • "As frequently as not though, there's no need to use dynamic memory at all in C++." That's entirely subjective to what you're developing. The OP's context is a game, in which case dynamic allocation is going to be unavoidable most of the time, and smart pointers would save a ton of time hunting down memory leaks. – derpface Oct 02 '14 at 15:18
  • @LokiAstari: A pointer _variable_ is also automatic in a function - the _memory_ it refers to is _dynamic_ - You mean "use stack allocated objects rather than heap allocated objects". – Johann Gerell Oct 15 '14 at 09:54
  • @JohannGerell: I DEFINITELY DO NOT.There is no concept of stack and heap in C++ (this is a Java concepts that java developers try and apply to C++ and causes a whole heap of problems). There are **automatic/static/thread/dynamic** storage duration objects. Though a pointer is an automatic storage duration object the object it refers to (in this case) is dynamic storage duration. In the C++ context when we are talking about objects memory management we are usually talking about the payload (not how it is referred to) and I am sure my comments are very clear to an C++ programmer in this context. – Martin York Oct 15 '14 at 15:06
  • @LokiAstari: _"I am sure my comments are very clear to an C++ programmer in this context"_ - I wouldn't bet my life on your assumption, even if I understand it. But let's leave it at that. – Johann Gerell Oct 15 '14 at 15:26
  • @JohannGerell: My point is that you should never be using the terms heap and stack when talking about C++ objects. Its just wrong and it is actively discouraged when it comes up in answers and comments. – Martin York Oct 15 '14 at 15:37

4 Answers4

11

For the usage shown, while the unique_ptr is better than a raw pointer as it indicates ownership of the allocated resources, you probably shouldn't use any kind of pointer at all. Instead just declare a local:

GameManager game;
game.Start();

This may not suffice if the ownership may have to be given to something else, whereas the ownership of a unique_ptr can easily be transferred.

Michael Urman
  • 15,286
  • 2
  • 24
  • 41
  • 1
    I up this answer as it points out - as another comment above - that one can very well live in C++ without any pointers, by placing objects on the stack. – Carsten Greiner Oct 02 '14 at 12:42
  • This should really be the accepted answer. The currently accepted answer makes it sound like heap-allocating locally scoped instances is preferable to stack allocated, which is seldom true. – Johann Gerell Oct 15 '14 at 10:00
8

To answer your question: yes, they do solve memory management problems.

It is considered good style to use them as much as possible.

They eliminate many possible programming errors, and reduce the difficulty of creating correct code with pointers.

To go even further, it is considered good to change

std::unique_ptr<GameManager> game (new GameManager());

To:

std::unique_ptr<GameManager> game (std::make_unique<GameManager>());
Michael Gazonda
  • 2,522
  • 1
  • 14
  • 31
  • 1
    Thank you for your fast answer, but what is with this answer to make_unique: http://stackoverflow.com/a/9657991/ ? – BendEg Sep 27 '14 at 16:54
  • @BendEg It's in c++14, and is widely available. – Michael Gazonda Sep 27 '14 at 16:56
  • Ok, i will read some thing about C++ 14, i thought it is no standard yet. (I use mvc++) – BendEg Sep 27 '14 at 16:58
  • 1
    c++14 is official now, and visual studio had make_unique available before the new standard came in – Michael Gazonda Sep 27 '14 at 17:00
  • 15
    The style I use is auto game = std::make_unique(); – paulm Sep 27 '14 at 17:07
  • 1
    Yes - its just less verbose and less change should the type be renamed – paulm Sep 27 '14 at 17:14
  • 2
    @BendEg No you **do** use smart pointer, `auto` just infer the type `unique_ptr` from the initializing expression. That style also seems more readable. – HiroshimaCC Oct 01 '14 at 18:23
  • But usually you will not create a smart pointer on the stack, it will more likely be a class member where you cannot use auto for type deduction. – Drax Oct 02 '14 at 09:52
  • @Drax: Just to expand on your comment - if you find yourself creating smart pointers in local scope in a function (on the stack), then you're most likely (unless there's no public constructor) better off just stack allocating the instance itself, not heap allocating it to be wrapped by the smart pointer. – Johann Gerell Oct 15 '14 at 09:58
3

In addition to the single ownership of unique_ptr, there are also situations where there is shared, or difficult to define ownership. In those cases, shared_ptr provides reference counting and the last owner will delete the referent.

In the cases where shared_ptr might be involved in a complex reference loop, the standard also provides weak_ptr.

All of these take the place of the older auto_ptr.

Craig M. Brandenburg
  • 2,624
  • 2
  • 22
  • 33
jbruni
  • 1,238
  • 8
  • 12
3

No, don't completely replace all raw pointers.

Using smart pointers (unique_ptr, shared_ptr) is only really useful for those pointers that own and manage the memory of the pointer. However, if a function takes a pointer as a parameter, then you don't want to transfer ownership. The function just needs to access the pointer.

void ShowCredits(GameManager* game)   // Just use game, don't take ownership.
{                                     // A raw pointer here is good.
   // ...
}

void main()
{
    auto game = make_unique<GameManager>(); // game owns the GameManager.
    game->Start();
    ShowCredits(game.get());
}

P.S. If ShowCredits relies on game always being valid (i.e. it can't optionally have a value of nullptr), you may actually be better off in this case with the parameter being of type GameManager&.

Scott Langham
  • 53,246
  • 34
  • 122
  • 193