c++shared-ptrsmart-pointersunique-ptrweak-ptr

Why can't a weak_ptr be constructed from a unique_ptr?


If I understand correctly, a weak_ptr doesn't increment the reference count of the managed object, therefore it doesn't represent ownership. It simply lets you access an object, the lifetime of which is managed by someone else. So I don't really see why a weak_ptr can't be constructed from a unique_ptr, but only a shared_ptr.

Can someone briefly explain this?


Solution

  • std::weak_ptr can't be used unless you convert it to std::shared_ptr by the means of lock(). if the standard allowed what you suggest, that means that you need to convert std::weak_ptr to unique in order to use it, violating the uniqueness (or re-inventing std::shared_ptr)

    In order to illustrate, look at the two pieces of code:

    std::shared_ptr<int> shared = std::make_shared<int>(10);
    std::weak_ptr<int> weak(shared);
    
    {
    *(weak.lock()) = 20; //OK, the temporary shared_ptr will be destroyed but the pointee-integer still has shared  to keep it alive
    }
    

    Now with your suggestion:

    std::unique_ptr<int> unique = std::make_unique<int>(10);
    std::weak_ptr<int> weak(unique);
    
    {
    *(weak.lock()) = 20; //not OK. the temporary unique_ptr will be destroyed but unique still points at it! 
    }
    

    That has been said, you may suggest that there is only one unique_ptr, and you still can dereference weak_ptr (without creating another unique_ptr) then there is no problem. But then what is the difference between unique_ptr and shared_ptr with one reference? or moreover, what is the difference between a regular unique_ptr and C-pointers an get by using get?

    weak_ptr is not for "general nonowning resources", it has a very specific job - The main goal of weak_ptr is to prevent circular pointing of shared_ptr which will make a memory leak. Anything else needs to be done with plain unique_ptr and shared_ptr.