Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

static unique_ptr calls destructor twice

I use a singleton pattern which returns a reference to unique_ptr dereference. Here is the code,

#include <iostream>
#include <memory>
using std::cout; using std::endl;
using std::unique_ptr;

namespace Settings {
    class Lazy {
        Lazy() { cout << "Lazy::Lazy() " << this << endl; }
    public:
        ~Lazy() { cout << "Lazy::~Lazy() " << this << endl; }
        static Lazy &instance()
        {
            static unique_ptr<Lazy> lazy(new Lazy);
            return *lazy;
        }
    };

    Lazy &lazy()
    { return Lazy::instance(); }
}

int main()
{
    cout << "main starts!" << endl;
    auto state = Settings::lazy();
    cout << "auto state = Settings::lazy() " << &state << endl;

    cout << "main ends!" << endl;
    return 0;
}

I was expecting that the destructor of the class would call only once but although the constructor called once destructor called twice, here is the output,

main starts!
Lazy::Lazy() 0xb1ec20
auto state = Settings::lazy() 0x7ffe17ae18b8
main ends!
Lazy::~Lazy() 0x7ffe17ae18b8
Lazy::~Lazy() 0xb1ec20

why destructor called twice? And even the second call this address is different.

like image 273
cavitsinadogru Avatar asked Mar 26 '16 21:03

cavitsinadogru


People also ask

Can a destructor be called twice?

The destructor will be called 2 times as there are two objects in a class. The destructor will be called as many times as there are objects in a class. The destructor of the last declared object will be called first and then the destructor of the first declared object. It will be called twice.

Does unique_ptr call destructor?

Yes. Well the unique ptr has a function object that by default invokes delete on the pointed to object, which calls the destructor. You can change the type of that default deleter to do almost anything.

How many times destructor is called?

The destructor is being called three times, for a , lol and b . In your case, a and b are instantiated using the default constructor .

What happens when unique_ptr goes out of scope?

An​ unique_ptr has exclusive ownership of the object it points to and ​will destroy the object when the pointer goes out of scope. A unique_ptr explicitly prevents copying of its contained pointer. Instead, the std::move function has to be used to transfer ownership of the contained pointer to another unique_ptr .


1 Answers

Because you have 2 instances of the singleton, and both get destroyed.

The reason why you have to 2 singletons, is that when you get the singleton auto state = Settings::lazy(); a copy is created. You might be returning a reference, but state isn't a reference, so a copy is created.

Making state a reference fixes the problem: auto& state = Settings::lazy();

like image 129
Rakete1111 Avatar answered Oct 25 '22 19:10

Rakete1111