shared_ptrs being deleted twice

I don't understand why the destructors are called twice.

Because of creating unnecessary temporary objects here:

std::shared_ptr<Object> p1(make_shared<Object>(Object(123)));
                                               ^^^
                                               temporary object

and here:

v.push_back(std::make_shared<Object>(Object(2)));
                                     ^^^
                                     temporary object

It should instead be

std::shared_ptr<Object> p1(make_shared<Object>(123));

and

v.push_back(std::make_shared<Object>(2));

Why?

Because std::make_shared constructs an object of type T and wraps it in a std::shared_ptr using args as the parameter list for the constructor of T. And in your code, you are making one extra object which immediately gets destroyed, thus calling the destructor.

Why don't you see Object(int n); constructor being called for temporary object?

Object(int n); constructor is indeed being called for the temporary object, but since the object held by the std::shared_ptr is created through copy constructor (so, by copying the temporary object) you won't see call to Object(int n); for it but call to Object(Object const& other);.

In the demo, you can see first Object(int n); constructor being called for the temporary object and then the call to copy constructor Object(Object const& other); for the actual object being referenced by the std::shared_ptr.


This is because you have to destroy the temporary values.

The std::make_shared function takes any amount of parameter and construct a value of the given type with it.

You construct a Object and pass it to std::make_shared, which in its turn construct a value using new. Then, the temporaries are destroyed. Later, the shared pointers also are destroyed.

Simply change this in your code:

std::shared_ptr<Object> p1(make_shared<Object>(123));

// ...  

v.push_back(std::make_shared<Object>(2));

And you'll see only one destructor for each values.