Sobes.tech
Middle

Is it possible to change the owner of the object pointed to by a unique_ptr?

sobes.tech AI

Answer from AI

Yes, it is possible. The owner of a unique_ptr can be changed in one of the following ways:

  1. Transfer ownership using std::move: A new unique_ptr can take ownership from an existing unique_ptr. The old unique_ptr becomes empty (null).

    #include <memory>
    
    int main() {
        auto ptr1 = std::make_unique<int>(10);
        auto ptr2 = std::move(ptr1); // ptr2 now owns the object, ptr1 is empty
    
        // The object with value 10 now belongs to ptr2
        // ptr1 no longer points to the object
    
        return 0;
    }
    
  2. Reset and assign: You can reset the current unique_ptr (free ownership and delete the object), then assign it either a new object or ownership from another unique_ptr (again using std::move).

    #include <memory>
    
    int main() {
        auto ptr1 = std::make_unique<int>(10);
        auto ptr2 = std::make_unique<int>(20);
    
        ptr1.reset(); // ptr1 becomes empty, object {10} is deleted
        ptr1 = std::move(ptr2); // ptr1 now owns the object {20}, ptr2 is empty
    
        return 0;
    }
    

    The reset(pointer) method also allows passing ownership of a new object or pointer from an external source, releasing the current object.

    #include <memory>
    
    int main() {
        auto ptr1 = std::make_unique<int>(10);
        int* raw_ptr = new int(20); // create an object outside of unique_ptr
    
        ptr1.reset(raw_ptr); // ptr1 now owns the object {20}, object {10} is deleted
    
        return 0;
    }
    
  3. Extract a "raw" pointer using release(): The release() method returns a "raw" pointer to the object owned by unique_ptr, and relinquishes ownership. unique_ptr becomes empty. This raw pointer can then be transferred to another object that will take ownership, such as another unique_ptr or manual memory management (with subsequent delete). Important: If the raw pointer is not transferred to an object that takes ownership, it will cause a memory leak.

    #include <memory>
    
    int main() {
        auto ptr1 = std::make_unique<int>(10);
        int* released_ptr = ptr1.release(); // released_ptr points to {10}, ptr1 is empty
    
        auto ptr2 = std::unique_ptr<int>(released_ptr); // ptr2 takes ownership of released_ptr
    
        // The object with value 10 now belongs to ptr2
        // released_ptr does not need manual deletion, as ptr2 now owns it
    
        return 0;
    }
    

Thus, unique_ptr guarantees exclusive ownership but allows explicit transfer of this ownership from one instance to another.