Singleton und ein komisches Verhalten
-
Hey Leutem,
ich have meine Fassadenklasse als Singleton impl. und jetzt Probleme mit so manchen member-varias.class Instance { public: static Instance* Instance(); void init(); //!< init all necessary classes and starts the threads private: //!< attendant for memory-clearing for singleton class Attendant { public: ~Attendant() { if( Instance::dInstance != 0 ) delete Instance::dInstance; } }; friend class Attendant; Instance(){} //!< constructor ~Instance(){} //!< destructor Instance(const Instance&); //!< copy constructor static GInstance *dInstance; //!< static instance Handler *handler; // func static void* threadreceive(void*); };In der oben (public) stehenden Funktion init() wird der Handlerpointer mit
handler = new Handler() init. Der Komp. schluck das auch aber zu laufzeit gibt es imma da ein Segmentationsfehler! Warum? Gibt in meinen Augen keinen sind (siehe public Instance())Instance* Instance::Instance() { static Attendant attendant; if (dInstance == 0) { dInstance = new dInstance(); //!< create an instance } return dInstance; }Wer weiss rat?!?!?!
lg
-
static GInstance *dInstance; //!< static instanceKann es sein das du uns eine weitere Klasse vorenthälst? Wo kommt GInstance in deinem Code vor? Weil ich sehe davon nur was in dem codestück, sonst nix?
-
Sorry, habe alle vorher umgenannt, G...Instance soll für euch nur Instance heißen. Sorry
-
davidwal schrieb:
Sorry, habe alle vorher umgenannt
Dabei sollte man aufpassen, dass die Klasse hinterher nicht heißt wie eine ihrer statischen Methoden.

Wie wird init denn aufgerufen?
-
Hmmm ich kann auch falsch liegen, aber meine erste Vermutung ist,deine Benennung der Instance() Methode.Bennen die spasses Halber mal um.
-
MFK schrieb:
davidwal schrieb:
Sorry, habe alle vorher umgenannt
Dabei sollte man aufpassen, dass die Klasse hinterher nicht heißt wie eine ihrer statischen Methoden.

Wie wird init denn aufgerufen?
So sind meine main() funktion aus.
Instance* Instance::dInstance = 0; //!< initialize Pointer int main(void) { GInstance* instance; // run instance->getInstance(); //!!! habe das GERADE so umgenannt getInstance() war Instance()!!! instance->init(); return EXIT_SUCCESS; }hier noch die init()
void Instance::init(){ // init threads pthread_t receive; pthread_create(&receive,NULL,&Instance::threadreceive,(void*)this); // init objects handler = new Handler(); /// hier krackt es (segmen. Fehler) while (true) { std::cout.flush(); } }
-
davidwal schrieb:
GInstance* instance;
instance ist ein unitialisierter Zeiger.
davidwal schrieb:
instance->getInstance();
Du rufst eine statische Methode über einen unitialisierten Zeiger auf. Keine Ahnung, was der Standard dazu sagt. Für statische Methoden brauchst du gar kein Objekt zum Aufrufen. getInstance gibt zwar einen gültigen Zeiger zurück, aber den Rückgabewert lässt du hintenüber fallen.
davidwal schrieb:
instance->init();
instance ist immer noch ein unitialisierter Zeiger -> PENG.
Das sollte wohl so aussehen:
Instance* instance = Instance::getInstance(); instance->init();Weiß der Geier, warum getInstance nicht gleich init aufruft.
-
Komisch, habe mal etwas probiert und es geht aus!!!!
in der init() Funktion:
handler = new Handler(); //durch getInstance()->handler = new Handler(); //ersetzen und voila, es geht!Nur leider verstehe ich dieses Verhalten nicht ganz!

-
MFK schrieb:
davidwal schrieb:
GInstance* instance;
instance ist ein unitialisierter Zeiger.
davidwal schrieb:
instance->getInstance();
Du rufst eine statische Methode über einen unitialisierten Zeiger auf. Keine Ahnung, was der Standard dazu sagt. Für statische Methoden brauchst du gar kein Objekt zum Aufrufen. getInstance gibt zwar einen gültigen Zeiger zurück, aber den Rückgabewert lässt du hintenüber fallen.
davidwal schrieb:
instance->init();
instance ist immer noch ein unitialisierter Zeiger -> PENG.
Das sollte wohl so aussehen:
Instance* instance = Instance::getInstance(); instance->init();Weiß der Geier, warum getInstance nicht gleich init aufruft.
g++
main.cpp: In function »int main()«:
main.cpp:15: Fehler: »Instance« wurde nicht deklariertZeile 15 Instance* instance = Instance::getInstance();

-
Also in dem Beispiel hier:
davidwal schrieb:
MFK schrieb:
davidwal schrieb:
Sorry, habe alle vorher umgenannt
Dabei sollte man aufpassen, dass die Klasse hinterher nicht heißt wie eine ihrer statischen Methoden.

Wie wird init denn aufgerufen?
So sind meine main() funktion aus.
Instance* Instance::dInstance = 0; //!< initialize Pointer int main(void) { GInstance* instance; // run instance->getInstance(); //!!! habe das GERADE so umgenannt getInstance() war Instance()!!! instance->init(); return EXIT_SUCCESS; }hier noch die init()
void Instance::init(){ // init threads pthread_t receive; pthread_create(&receive,NULL,&Instance::threadreceive,(void*)this); // init objects handler = new Handler(); /// hier krackt es (segmen. Fehler) while (true) { std::cout.flush(); } }Heißt es ja bei dir immernoch GInstance, vielleicht wieder Vergessen umzubennen?
-
davidwal schrieb:
Nur leider verstehe ich dieses Verhalten nicht ganz!

Ganz einfach, dein this-Zeiger ist hier ungültig, weil du init über einen unitialisierten Zeiger aufrufst. Mit dem Zeiger aus getInstance geht's natürlich, ändert aber nichts am grundsätzlichen Problem.