pss
pss

Reputation: 95

shared_ptr::reset only works with raw pointers?

I have always seen the smart pointer reset function used with raw pointers. When I try to pass another smart pointer to it, it fails. I looked here: http://en.cppreference.com/w/cpp/memory/shared_ptr/reset but it does not say much about this. Just want to confirm if this is the case? My code is here: https://wandbox.org/permlink/xKNtJhjGeOSZS7KN Also here for your convenience:

#include<iostream>
using std::cout; using std::endl;
#include<memory>
using std::shared_ptr;

class Widget
{
public:
  ~Widget()
  {
    cout << "Hi from destructor" << endl;
  }
};

auto wdel = [](Widget* pw)
            {
              cout << "Hi from custom deleter" << endl;
              delete pw;
            };

int main()
{
  {
    shared_ptr<Widget> pw(nullptr,wdel);
    pw.reset(new Widget);
    cout << "Done reset" << endl;
    shared_ptr<Widget> pw2(nullptr,wdel);
    // pw = pw2;   // this works
    pw2.reset(pw); // this does not work
  }
  return 0;
}

Thank you in advance.

Upvotes: 0

Views: 760

Answers (2)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275310

Implicit conversion from smart pointers to raw pointers is very dangerous. So it doesn't happen.

If a smart pointer thinks it is managing a pointer that another smart pointer is managing, both will think they have the right to clean it up. And bad things will usually happen when the second one does the cleanup.

A raw pointer doesn't contain ownership information.

On the other hand, when you assign one shared pointer to another, the information about the lifetime of the pointer is also shared. So the two cooperatively manage the pointers lifetime, and the last one to leave skope does the cleanup.

Upvotes: 3

Caleth
Caleth

Reputation: 62606

pw2 = pw is the correct thing, and only copies (using shared_ptr::operator& or shared_ptr::shared_ptr) can be correct.

Consider if there were a third shared_ptr. That has as much right to keep the ownership as pw, so pw can't be allowed to transfer ownership somewhere else.

You can do pw2 = pw; pw.reset(nullptr); to release pws ownership to pw2, because that doesn't affect other pointers sharing the Widget.

Upvotes: 4

Related Questions