C++ Mehrere Klasseninstanzen verhindern

Xtremebergi

Lt. Junior Grade
Registriert
Feb. 2008
Beiträge
312
Hallo, Leute, ich bin mit meinem Latein am Ende


Ich habe eine Klasse mit einer statischen Membervariablen. Normalerweise heißt das, dass es diese Variable nur 1x im ganzen Programm gibt (zumindest war es in C# und Java so).

Die statischen Membervariablen werden ja in der .cpp-Datei extra initialisiert/definiert. Dort hab ich einen Breakpoint gesetzt...diese Definition wird mehrere Male aufgerufen! Ich hab das Programm dann auch mal weiterlaufen lassen und gemerkt dass Funktionen verschiedener Sourcefiles nicht die gleichen statischen Membervarialben verwenden...das ist schlecht.

Ich habe schon stundenlang im Internet nach einer lösung gesucht und zwar erfahren, dass dieses Problem bekannt ist ("static initialization order fiasco", etc.), aber nicht, wie ich garantieren kann dass diese Variable wirklich nur EINMAL existiert.

Bitte um Hilfe, ich weiß echt nicht mehr weiter.:(


Danke im Voraus
Bergi
 
Oh, man, ich bin so blöd, ich schreib "Klasseninstanzen"...klar dass es da es da Missverständnisse gibt...

Ok, ich meinte damit die Klassenobjekte...es gibt ja immer die Instanzen der Klasse und dann noch das Klassenobjekt selber...
 
Hast du dir das hier mal angesehen? Da wird eine Lösung erläutert.

Ansonsten häng doch mal Quellcode von einem Minimalbeispiel mit dem Problem an.
 
Ja, da wird halt damit gelebt, dass es 2 Klassenobjekte gibt, und es wird geschaut wie man das Problem beheben kann, dass man nicht weiß, welches zuerst erstellt wird (so habs ich zumindest verstanden).
 
7H3 N4C3R schrieb:
Singleton ist übrigens ein Antipattern. Gewöhn es dir lieber garnicht erst an.

So ein Nonsens!


Zum Thema: Singleton-Pattern ist eigentlich sehr einfach. Wenn du nicht gerade Multithreaded auf die Routine zugreifst gibt es tatsächlich nur eine einzelne Instanz.
Beispiel: Dein gewünschtes Objekt ist von der Klasse C, dann kannst du die folgendermaßen modifzieren (kurzform):

Code:
class C {
public:
 static C *getInstance() {
   static C *instance = NULL;
   if (instance == NULL) {
     instance = new C();
   }
   return instance;
 }
};

Die Konstruktoren von C machst du dann am besten alle protected oder private, dann kannst du das Objekt nur durch getInstance() erzeugen und nicht mehr einfach über new C();

Wenn du auf dein Objekt zugreifen willst machst du das hier:
Code:
C *obj = C::getInstance();
 
Ich glaub ich hab meinen Fehler...bin mir aber noch nicht sicher...


Edit:
Ok, ich habs, es war viel ersichtlicher, als ich mir dachte...eigentlich hätte ich gleich draufkommen können.

Das Problem ist, es ist ein template (sorry, hätt ich vielleicht dazuschreiben sollen)...ja und da herschen so manch andere Gesetze. Jedenfalls wird natürlich für jeden neuen Typ, für den es verwendet wird, eine neue Klasse erzeugt, und natürlich werden dann auch alle statischen Member vervielfältigt.

Ich hab das Template jetzt von einer Basisklasse abgeleitet und die statische Membervariable, die es nur EINMAL geben soll, dort hingegeben...und siehe da, sie ist jetzt wirklich nur noch einmal da...jippi^^
 
Zuletzt bearbeitet:
IceMatrix schrieb:

Hehe, die Diskussion hatten wir schonmal. ;) Führt hier in diesem Thread wohl zu nix. *g*
Dein Singleton-Beispiel zerstört sich niemals.

@Xtremebergi:
Jipp, aus einem Klassentemplate werden mehrere Templateklassen. Damit vervielfältigen sich die statischen Member auch pro Typ.
 
Zuletzt bearbeitet:
IceMatrix schrieb:

Im übrigen ist es sehr schlechter Stil in C++ Rohzeiger zu verwenden. Noch schlimmer ist es wenn man Rohzeiger zurück gibt. Ich rate dir dringend sich mit Smart Pointern auseinanderzusetzen.

Dass diese Instanz nie gelöscht wird, kann keinesfalls gewollt sein. Es ist sogar ein Vergehen es dem Betriebssystem zu überlassen, da nie zu 100 Prozent entschieden werden kann ob nun ein Memory Leak vorliegt oder nicht.
 
Ich persönlich finde Singletons auch sehr unschön, aber wenn man unbedingt einen will und das Problem des nie durchlaufenen Destruktors umgehen möchte, kann man den Singleton ja auch ohne freestore-Allokierung anlegen:

Code:
#include <iostream>

class TestSingleton
{
public:
	static TestSingleton& getInstance()
	{
		static TestSingleton myInstance;
		return myInstance;
	}

private:
	TestSingleton()
	{
		std::cout << "Instance created at address 0x" << std::hex << this << std::dec << "\n";
	}

	~TestSingleton()
	{
		std::cout << "Destroying instance at address 0x" << std::hex << this << std::dec << "\n";
	}
};

int main()
{
	TestSingleton::getInstance();
	TestSingleton::getInstance();
}
 
Ich verstehe einfach den Sinn von dem ganzen Ding nicht. Wenn man nur eine Instanz von einer Klasse braucht, warum legt man eben nicht nur eine Instanz an und fertig? Wozu haufenweise Boilerplate-code für solche "tollen" Dinge wie Singletons und Singularities schreiben? Na ja, jedem das seine ... ;)


P.S. Im übrigen sollten wir die Diskussion vielleicht in einem anderen Thread weiterführen, da das eigentliche Thema dieses Threads ja ein ganz anderes war.
 
Zurück
Oben