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 instance
    

    Kann 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 deklariert

    Zeile 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.


Anmelden zum Antworten