What does unique_ptr<T>::operator= do in terms of deallocation

unique_ptr example
unique_ptr assignment
unique_ptr::reset
unique_ptr vs shared_ptr
unique_ptr deleter
unique_ptr move
delete unique_ptr
unique_ptr::get

I'm having troubles understanding fully the assignment operator for unique_ptr. I understand that we can only move them, due to the fact that copy constructor and assignment operators are deleted, but what if a unique_ptr which contains already an allocation is overwritten by a move operation? Is the content previously stored in the smart pointer free'd?

#include <iostream>
#include <memory>

class A{
public:
    A() = default;
    virtual void act() const {
        std::cout << "act from A" << std::endl;
    }
    virtual ~A() {
        std::cout << "destroyed A" << std::endl;
    }
};
class B : public A {
public:
    B() : A{} {}
    void act() const override {
        std::cout << "act from B" << std::endl;
    }

    ~B() override {
        std::cout << "destroyed from B " << std::endl;
    }
};
int main() {
    auto pP{std::make_unique<A>()};
    pP->act();

    ==================== ! =======================
    pP = std::make_unique<B>(); // || std::move(std::make_unique<B>())
    ==================== ! =======================

    pP->act();
    return 0;
}

When I do

pP = std::make_unique<B>();

does it mean that what was allocated in the first lines for pP (new A()) is destructed automatically? Or should I opt for:

pP.reset();
pP = std::make_unique<B>();

std::unique_ptr - unique_ptr, This class template is deprecated as of C++11. unique_ptr is a new facility with a So, when using unique_ptr there can only be at most one unique_ptr at any  std::unique_ptr is a smart pointer that owns and manages another object through pointer. std::unique_ptr has unique ownership of the object. That means only one std::unique_ptr can have the ownership of the actual object. We can not assign a std::unique_ptr object to another smart pointer.

Yes, replacing the content of a smart pointer will release the previously-held resource. You do not need to call reset() explicitly (nor would anyone expect you to).

auto_ptr, unique_ptr, shared_ptr and weak_ptr, unique_ptr is defined in the <memory> header in the C++ Standard Library. It is exactly as efficient as a raw pointer and can be used in C++  unique_ptr objects replicate a limited pointer functionality by providing access to its managed object through operators * and -> (for individual objects), or operator [] (for array objects). For safety reasons, they do not support pointer arithmetics, and only support move assignment (disabling copy assignments).

Just for the sake of this particular example. It seems polymorphism in your example didn't allow you to draw clear conclusions from output:

act from A
destroyed A
act from B
destroyed from B 
destroyed A

So let's simplify your example and make it straight to the point:

#include <iostream>
#include <memory>

struct A {
    explicit A(int id): id_(id)
    {}

    ~A()
    {
        std::cout << "destroyed " << id_ << std::endl;
    }

    int id_;
};

int main() {
    std::unique_ptr<A> pP{std::make_unique<A>(1)};
    pP = std::make_unique<A>(2);
}

which outputs:

destroyed 1
destroyed 2

Online

I hope this leaves no room for misinterpretation.

How to: Create and use unique_ptr instances, The constructor of unique_ptr<T> accepts a raw pointer to an object of type T (so, it accepts a T* ). In the first example: unique_ptr<int> uptr  unique_ptr is defined in the <memory> header in the C++ Standard Library. It is exactly as efficient as a raw pointer and can be used in C++ Standard Library containers. The addition of unique_ptr instances to C++ Standard Library containers is efficient because the move constructor

How to declare std::unique_ptr and what is the use of it?, unique_ptr<> is one of the Smart pointer implementation provided by c++11 to prevent memory leaks. A unique_ptr object wraps around a raw  unique_ptr assignment The object acquires the ownership of x 's content, including both the stored pointer and the stored deleter (along with the responsibility of deleting the object at some point). Any object owned by the unique_ptr object before the call is deleted (as if unique_ptr's destructor was called).

C++11 Smart Pointer – Part 6 : unique_ptr Tutorial and Examples , As a result, unique_ptr objects can be stored in containers, work properly when containers are resized or moved, and will still be destroyed when  std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope.

C++11: unique_ptr, A unique_ptr variable is said to be the owner of the object it points to: if the owner dies without passing its ownership to another variable, the  std::unique_ptr::release. pointer release() noexcept; Releases ownership of its stored pointer, by returning its value and replacing it with a null pointer. This call does not destroy the managed object, but the unique_ptr object is released from the responsibility of deleting the object.

Comments
  • what have you got in output? do you see that the first instance was destroyed? did this answer your question?
  • Considering it was a polymorphic call I had "act from A" "destroyed from A", the next part is obvious. But I needed some clarification, even tho I did debug the code in order to see the internals of unique_ptr.
  • @AndriyTylychko Trying something out and seeing what happens doesn't tell you anything about what's supposed to happen or is guaranteed to happen.
  • @Cubic: let's be realistic and not pedantic. OP asks about very basic C++ staff and if any C++ compiler behaves not according to C++ standard in such basic cases it's literally dead and not worth to be mentioned. I was trying to understand the root of OP's confusion to potentially show the way how to avoid it in the future.
  • @AndriyTylychko How is a beginner going to tell the difference between "basic" stuff and stuff that's not basic? There are a lot of situations that are unspecified or undefined that seem perfectly reasonable to many beginners.
  • Thank you, I'm following other books in which such thing was not specified, too bad.
  • @AlexNyken The C++ standard is quite verbose by necessity, it's not surprising that teaching books won't spell out everything it says. The authors of your book probably didn't think it was necessary to mention at the time or might've even thought it was obvious (or otherwise, they might've mentioned it as an offhand remark that you missed).
  • Most definitely
  • Thank you a bunch