0

With normal pointers, I can declare a pointer and then set it equal to a new object, however with shared pointers I am unable to do that. Why?

#include <memory>
struct node{
    int num;
    node* next;
};
int main()
{
    std::shared_ptr<node> new_node1 = NULL; // WORKS
    new_node1 = new node;   // ERROR, why?
    node* new_node2 = NULL; //WORKS
    new_node2 = new node;   //WORKS

    return 0;
}

Why can't we create a new object for a shared pointer? Is there a way to do it?

Rimoun
  • 455
  • 1
  • 9
  • 16
  • 4
    [`reset()`](http://en.cppreference.com/w/cpp/memory/shared_ptr/reset). – Captain Obvlious May 19 '15 at 23:40
  • How would I use reset() to do this? – Rimoun May 19 '15 at 23:41
  • 2
    `new_node1.reset (new node);` or `new_node1 = std::make_shared ();` – David Schwartz May 19 '15 at 23:41
  • 1
    The answer to that was a click away. Lazy :\ – Captain Obvlious May 19 '15 at 23:42
  • The short answer to your first question is that if you could do so easily, terrible things would happen. Consider `Foo *f = new Foo(); bar(f); bar(f);`. Now, what happens if `bar` takes a `std::shared_ptr`? (Think about the destruction of the temporary shared pointer.) You want to know for sure where and when you are constructing a `shared_ptr` because that takes over control of the lifetime of the underlying object. – David Schwartz May 20 '15 at 00:00
  • [same question with unique_ptr](http://stackoverflow.com/questions/29992806/) – Ryan Haining May 20 '15 at 00:34

2 Answers2

4
std::shared_ptr<node> n(new node);
n.reset(new node);
n = std::make_shared<node>();

You should prefer make_shared

Tas
  • 7,023
  • 3
  • 36
  • 51
2

This is because the constructor that would be called during the operator=() call is marked as explicit.

To work around this:

new_node1 = std::shared_ptr<node>(new node);

Or:

new_node1 = std::make_shared<node>();
Bill Lynch
  • 80,138
  • 16
  • 128
  • 173