xhassassin
xhassassin

Reputation: 283

Upgradeable pointer (unique_ptr -> shared_ptr)

I'm told that shared_ptr is much slower than unique_ptr, so you should always strive to use unique_ptr's when possible. I have a potential use case where one object will have a single owner the majority of the time, but may have multiple owners in some scenarios. In this case, is there any sort of implementation of a unique_ptr that can be upgraded to a shared_ptr when needed instead of having everything be declared as a shared_ptr in the first place?

IE instead of using shared_ptr, would it be more beneficial if I used something like the following if the case of upgrading is very rare, or is there some pitfall I'm not seeing here?

class upgrade_ptr<T> {
  shared_ptr<T> shared_;
  unique_ptr<T> unique_;
  upgrade_ptr(T obj) {
    unique_ = unique_ptr<T>(obj);
  }
  shared_ptr<T> share() {
    if (shared_ == nullptr) {
      shared_ = shared_ptr<T>(unique_);
    }
    return shared_;
  }
}

Upvotes: 3

Views: 105

Answers (1)

J. D.
J. D.

Reputation: 113

std::shared_ptr is slower than std::unique_ptr because it keeps track of the number of std::shared_ptr instances managing the same object. std::unique_ptr instances do not do this. That means that every time a std::unique_ptr instance's destructor is called, the managed object is deleted as well, whereas a std::shared_ptr instance only deletes the managed object when it is the last instance pointing to this object upon destruction.

With that being said, your upgrade function can look something like this:

template<class T>
std::shared_ptr<T> upgradePointer(std::unique_ptr<T> &u)
{
    return std::shared_ptr<T>(u.release());
}

Downgrading, on the other hand, can not be done so easily, because there is no way to tell a std::shared_ptr to stop managing a certain object.

Hope that helps.

Upvotes: 3

Related Questions