1

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?

Sajib
  • 404
  • 3
  • 15

2 Answers2

9

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
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
2

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
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • 1
    https://i.stack.imgur.com/5P2qL.png are you happy now? :D – Aykhan Hagverdili Jun 07 '21 at 10:03
  • @463035818_is_not_a_number No no it's absolutely fine. Let's delete off this discussions XD and make SO cleaner – anirudh Jun 07 '21 at 10:08
  • Thanks. It was to the point explained. :D – Sajib Jun 07 '21 at 10:11
  • @463035818_is_some property_number: Also you change your mind. how 463035818 can be the largest prime number and not a number depending of the month or your feeling? ;-) – Jarod42 Jun 07 '21 at 10:11
  • 1
    Suggestion for the next time: 463035818_is_not_a_random_number, to mismatch with explanation *"463035818 is just a random number, nothing more"* ;-) – Jarod42 Jun 07 '21 at 10:21
  • 1
    @anirudh I was asked about the number so frequently recently that now eventually I wrote it up in my profile. Yes we can clean some comments, next time I can simply refer to my profile – 463035818_is_not_an_ai Jun 07 '21 at 10:41
  • @463035818_is_not_a_number hahaha dude you took this to next level ! But definitely your Bio would now help some other curious & troublesome SOers like me ! – anirudh Jun 07 '21 at 14:06
  • @463035818_is_not_a_number I truly appreciate your efforts & intention behind changing your username. I should take some inspiration from you :) – anirudh Jun 07 '21 at 14:09
  • @463035818_is_not_a_number Great People (like you) , make the Great Communities like SO. Thanks sir :) – anirudh Jun 07 '21 at 14:17
  • @463035818_is_not_a_number I respect your anonymity but would definitely like to connect with you on Linkedin. – anirudh Jun 07 '21 at 14:19