Sajib
Sajib

Reputation: 414

unique_ptr is calling destructor twice

I have a block of code where I am using unique_ptr.

class Abc {
public:
    std::string msg;
    Abc(std::string m) {
        msg = m;
        std::cout << "Constructor: " << msg << std::endl;
    }  
    ~Abc() {
        std::cout << "Destructor: " << msg << std::endl;
    }
};


int main() {
    auto p = std::make_unique<Abc>(Abc(__func__));
}

But the destructor is called two times. Is there a way I can make it call the destructor only one time?

Upvotes: 1

Views: 896

Answers (2)

songyuanyao
songyuanyao

Reputation: 172894

You're constructing a temporary Abc (i.e. Abc(__func__)) firstly, then pass it to std::make_unique, which constructs the underlying Abc from the temporary (via the move constructor of Abc); i.e. two Abc objects are constructed, then destructor are called twice too.

You can pass __func__ to std::make_unique directly, i.e. needn't to construct the temporary Abc from the beginning.

auto p = std::make_unique<Abc>(__func__); // constructs Abc via Abc::Abc(std::string) directly

Upvotes: 9

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122228

You create two objects and see both of them destructed. Abc(__func__) is a temporary that gets destroyed at the end of the line in main.

Add a user defined move constructor to see how make_unique move constructs the object:

#include <string>
#include <memory>
#include <iostream>

class Abc {
public:
    std::string msg;
    Abc(std::string m) {
        msg = m;
        std::cout << "Constructor: " << msg << std::endl;
    }
    Abc(Abc&& other){
        msg = other.msg + " moved";
        std::cout << "Move Constructor: " << msg << "\n";
    }  
    ~Abc() {
        std::cout << "Destructor: " << msg << std::endl;
    }
};


int main() {
    auto p = std::make_unique<Abc>(Abc(__func__));
}

Output:

Constructor: main
Move Constructor: main moved
Destructor: main
Destructor: main moved

Upvotes: 2

Related Questions