[C++] private static member aendert wie von Geisterhand den Wert.

DataNaut

Cadet 2nd Year
Registriert
Nov. 2005
Beiträge
31
Ja, ich weiss, das geht nicht.
Fuer ein Singleton habe ich grob folgenden Aufbau:

singleton.h

Code:
class singleton {
	
public:
	static id_singleton * get_instance();
	static void destroy();
	// usw..
private:
	
	singleton ();
	~singleton ();

	// singelton pointer
	static singleton * p_instance;

	// usw..
};


singleton.cpp

#include "singleton.h"

singleton*  singleton:: p_instance = NULL;
singleton* singleton:: get_instance()
{
     if (!p_instance)	
      {
        p_instance = new singleton();
      }
    return p_instance;
}

void singleton::destroy()
{
	
	delete p_instance;
	p_instance = NULL;
}


singleton::singleton () 
	{
	p_instance = this;	
	}

singleton::~singleton()
	{
		
	}


So und ähnlich gibt es sechs Singeltons in meinem Programm. Das
p_instance = this;
im Konstruktor ist notwendig, da sich einige der Singeltons gegenseitig aufrufen. Das ganze funktioniert wie erwartet sehr schön. Beim initialisieren bauen sich die Singeltons, meist Managers auf, benutzen sich gegenseitig, und es gib immer nur einen von jeder Sorte.
So weit so gut.
Ab irgend einem Punkt, und ich kann diesen Punkt auch nicht genau beschreiben, verwandeln sich die singleton * p_instance in NULL. Nun sind sie privat und nur durch Zugriffsmethoden benutzbar. Ausgaben in der destroy() Methode haben nichts ergeben.
Ich habe mir den Pointer in den get_instance methoden ausgeben lassen, und manchmal ist er plötzlich NULL. Wie kann das sein?
Kann es sein, dass die Initialisierung
Code:
singleton* singleton:: p_instance = NULL;
noch mal gemacht wird?
Zum Aufbau des Ganzen vielleicht noch:
Die Hauptklasse ist ein ObjectManager, der ein Singelton ist. Dieser instantiiert verschiedene andere Manager auch als Singletons. Das Ganze wird in eine statische lib gepackt und gegen das Hauptprogramm gelinkt, welches nur den ObjectManager kennt und ihn instantiiert.
Vier nicht ganz dumme Programmier haben schon Stunden auf den Code geglozt und hoffen von Euren Loesungsvorschlaegen Erloesung
Vielen Dank
DataNaut
 
Moin

Wieso benutzt du im Header
Code:
static id_singleton * get_instance();
und gibst im Code ein singleton zurück?

Probier mal im Header
Code:
static singleton * get_instance();
Das bringt das ganze eventuell durcheinander.

Gruß
Cobinja
 
Außer das was Cobinja angemerkt hat:

- Nur um sicher zu gehen - da du 6 verschiedene Singletons hast - du hast auch 6 verschiedene Quelldateien mit jeweils einer statischen Variable?

- Hast du auch Kopierkonstruktur und Zuweisungsoperator deaktiviert (private gemacht)?

- Du leitetst von dem Ding doch auch nicht ab, oder?

Kann es sein, dass die Initialisierung
Code:

singleton* singleton:: p_instance = NULL;

noch mal gemacht wird?
Nein. Nur einmal pro Übersetzungseinheit.

Und nochwas:
Das
p_instance = this;
im Konstruktor ist notwendig, da sich einige der Singeltons gegenseitig aufrufen.
Das klingt schonmal sehr sehr unangenehm. Ich denke da liegt der Hund irgendwo begraben.




Noch eine Anmerkung: Warum kein Meyers-Singleton? Dann erspart man sich das ganze Pointer-Gefrickel und das Ding zersört sich von alleine.
Code:
class Singleton
{
public:
  Singleton& instance() { static Singleton s; return s; } // inline implementation gehört natürlich in ein cpp file, ist nur der übersichtlichkeit hier
private:
  Singleton() {};
  ~Singleton() {};
  Singleton( const Singleton&);
  Singleton& operator=( const Singleton&);
};
 
Zuletzt bearbeitet:
hallo Cobinja,
das war ein Rechstschreibfehler von mir, im Code ist das nicht so.
mercí trotzdem.
hallo 7H3 N4C3R,
ich habe sechs verschieden quelldateien, mit verschiedenen statics

- Hast du auch Kopierkonstruktur und Zuweisungsoperator deaktiviert (private gemacht)?
habe ich nicht, aber ich dereferenziere nicht, und Kopiere nicht. Um das ganze Wasserdicht zu machen, werde ich das tun.

Nein, ich leite nicht von den Klassen ab. (war aber auch eine Idee, die ich hatte, hat nicht geklappt.:rolleyes: )
 
Welchen Compiler verwendest du? Hast du mal Memory-Breakpoints versucht?

Falls das nix hilft - mehr Code bitte. Kannst du es eingrenzen, wann die Nullzeiger auftreten? Ist das vielleicht nur eine Folge davon, dass irgendwo anders Speicher geschrottet wird? Hast du einen Memory-Checker, den du auf das Programm werfen kannst?
 
Zuletzt bearbeitet:
Vielleicht liegt es auch an der statischen Lib. Füge die Dateien mal Deinem Projekt hinzu und kompiliere sie mit.

Ansonsten könnte es auch ein Überschreiber sein.

MfG

Arnd
 
... bin noch am suchen ... wenns was neues gibt, meld ich mich.
 
Beim genaueren hinsehen ist mir aufgefallen:
Die singletons befinden sich in einer lib, die von einem anderern Programmteil gelinkt wird.
Nennen wir das Teil DMUManager.
Dieser andere Programmteil wird seinerseits als dll von dem Hauptprogramm geladen.
Wenn ich irgendwo im DMUManager auf die Singletons zugreife,funktioniert es wunderbar.
Wenn ich aber vom Hauptprogramm aus , welches den DMUManager mit den Singletons als dll geladen hat, auf die Singletons zugreifen will, dann geht es nicht.

Irgendwo in meinem Hinterkopf klingelt es wegen dlls und statischen Variablen, ich weiss nicht wo....
Irgendwelche Ideen?
Wir arbeiten mit Visual C++ 2003.net Version 7.1


Gruss
DataNaut
 
Wie ich vermutet habe, linke die betroffenen Files mal nicht als Lib sondern direkt zum Hauptprogramm bzw. alternativ in die DLL dann geht es vielleicht.
Bzgl. dll und statischen Variablen müsste ich auch erst mal in der Doku stöbern.

MfG

Arnd
 
Zurück
Oben