2016-03-26 11 views
1

Ich benutze ein Singleton-Muster, das einen Verweis auf unique_p Dereferenz zurückgibt. Hier ist der Code,static unique_ptr ruft Destruktor zweimal auf

#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; 
} 

Ich hatte erwartet, dass der Destruktor der Klasse nur einmal nennen würde, aber obwohl der Konstruktor einmal destructor zweimal aufgerufen genannt, hier ist der Ausgang,

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

warum destructor genannt zweimal? Und selbst beim zweiten Anruf ist diese Adresse anders.

+2

'auto Zustand = Einstellungen :: faul();' ruft die automatische Copykonstruktor, die Sie in jede Spur Ausgang nicht haben. Erstellen Sie einen privaten, wenn Sie wirklich einen Singleton wollen, und Sie werden den Fehler sehen. –

+0

Warum ein 'unique_ptr' verwenden? Könnte auch nur ein statisches Objekt haben. – Galik

+1

Ich empfehle diese Antwort zu betrachten: http://StackOverflow.com/a/1008289/3807729 – Galik

Antwort

4

Weil Sie 2 Instanzen des Singleton haben und beide zerstört werden.

Der Grund, warum Sie 2 Singletons haben müssen, ist, dass, wenn Sie das Singleton auto state = Settings::lazy(); erhalten, eine Kopie erstellt wird. Möglicherweise geben Sie eine Referenz zurück, aber state ist keine Referenz, daher wird eine Kopie erstellt.

machen state eine Referenz behebt das Problem: auto& state = Settings::lazy();