c++ Singleton problem (Konstruktor 1x aufgerufen, Destruktor beliebieg oft.)
-
Ich möchte eigentlich ein Singleton aufbauen, dass irgendwelche events in ein logfile schreibt(Singleton, damit die Datei nur einmal geöffnet ist). Jedoch trat hierbei ein seltsames verhalten des Objekts auf: es ändert seine inneren (dynamischen) Zustände nicht. Außerdem wird der Destructor jedes mal, nachdem die Funktion "run()" aufgerufen wurde, ausgeführt.
Hier habe ich ein Minimalbeispiel erstellt#include <stdio.h> class Singleton { public: static void run(){getInstance().inc();} private: int counter; static Singleton getInstance(); Singleton(); ~Singleton(); static Singleton* Instance; void inc() { printf("%d\n",counter); counter=counter+1; } }; Singleton* Singleton::Instance=NULL; Singleton Singleton::getInstance() { if (Instance==0) Instance=new Singleton(); return *Instance; } Singleton::Singleton() { counter=1; printf("Constructor\n"); } Singleton::~Singleton() { printf("Destructor\n"); } int main() { Singleton::run(); Singleton::run(); Singleton::run(); getchar(); }Als Ausgang hätte ich erwartet:
Constuctor 1 2 3 (möglicherweise) DestructorErhalten habe ich jedoch (mit minGW C++ und Visual Studio)
Zwei Fragen hierzu:
1. Warum wird die variable counter des Objekts Instance nicht geändert?
2. Warum kann das Objekt 3 mal zerstört werden, obwohl es nur einmal erstellt wurde?
-
Denk mal über den Code nach?
Singleton Singleton::getInstance() { if (Instance==0) Instance=new Singleton(); return *Instance; }Tipp: Wertsemantik
Lösung: du willst ne Referenz von Singleton zurückgeben.
-
Vielleicht mal das Meyers-Singleton anschauen.
Ach ja, und eine private
getInstance()-Methode macht natürlich besonders viel Sinn.
-
-
Klasse, vielen Dank.
Ich habe die Originalvariante "verreinfacht", jedoch war mir dabei nicht bewusst, dass ich so nur eine Kopie mitliefere.
Ich wundere mich jedoch immer noch, warum der Dekonstruktor bei den Kopien jedes mal implizit aufgerufen wird. Wenn ich jedoch die Referenz mitgebe nie.
-
alex29 schrieb:
Ich wundere mich jedoch immer noch, warum der Dekonstruktor bei den Kopien jedes mal implizit aufgerufen wird. Wenn ich jedoch die Referenz mitgebe nie.
Destruktor!
Der Destruktor wird aufgerufen, weil automatische und temporäre Objekte am Ende ihres Gültigkeitsbereiches zerstört werden. Mit der Referenz erstellst du hingegen kein neues Objekt.
-
Ergänze mal den Copy-Constructor und dir wird evtl. ein Licht aufgehen

Singleton(const Singleton& c);Singleton::Singleton(const Singleton& c){ std::cout << "copy" << std::endl; this->counter = c.counter; }
-
Singleton Singleton::getInstance() { if (Instance==0) Instance=new Singleton(); return *Instance; }->
/* static */ Singleton& Singleton::getInstance() { static Singleton onlyOne; return OnlyOne; }