Meyers singleton als Speicher für Variablen



  • Hallo,
    ich will Parameter (myInt) in einem Meyer-Singleton speichern.
    Derselbe Parameter soll gesetzt werden und von zwei verschiedenen cpp Files benutzt werden.
    Was ist dafür der richtige Weg?

    Etwa:

    // .h
    class MySingleton{
    public:
    	static MySingleton& getInstance(){
    		static MySingleton instance;		
    		return instance;
    	}
    	static void setInt(int var) {
    		myInt = var;
    	}
    	static int getInt() {
    		return myInt;
    	}
    private:
    	MySingleton() = default;
    	~MySingleton() = default;
    	MySingleton(const MySingleton&) = delete;
    	MySingleton& operator=(const MySingleton&) = delete;
    
    public:
    	static int myInt;
    };
    
    // .cpp
    int MySingleton::myInt = 0;
    
    
    // .cpp Nutzung Stelle A
    MySingleton::getInstance().setInt(1);
    int test = MySingleton::getInstance().getInt();
    
    // .cpp Nutzung Stelle B
    int test = MySingleton::getInstance().getInt();
    


  • @Mond Der Trick an einem Meyer Singleton ist, dass man die einzige Instanz, die auf den internen Zustand des Singleton Objektes zugreifen kann, über die GetInstance Methode bekommt.

    Du gehst jetzt aber hin und machst weitere statische Member und Funktionen die eben ohne diese Singleton Instanz arbeiten können. Das konterkariert die ganze Sache.



  • @Mond
    Warum willst du einen int in ein Meyers' Singleton einwickeln?
    Weisst du was der Sinn von Meyers' Singleton ist?



  • Danke für die Hinweise. Grundsätzlich war Int nur ein Beispiel. Grund für die Nutzung ist divers, u.a. Vermeidung von verschiendenen Fiaskos und Thread-Safety.
    Alternative Herangehensweise für die Anforderungen nehme ich gerne.



  • OK.

    Also der grösste Fehler in deinem Code ist dass du myInt static gemacht hast. myInt soll ja in der MySingleton Instanz eingewickelt sein. Das geht natürlich nur wenn es nicht static ist. Also

    class MySingleton{
    public:
    	static MySingleton& getInstance(){
    		static MySingleton instance;		
    		return instance;
    	}
    	void setInt(int var) {
    		myInt = var;
    	}
    	int getInt() {
    		return myInt;
    	}
    private:
    	MySingleton() = default;
    	~MySingleton() = default;
    	MySingleton(const MySingleton&) = delete;
    	MySingleton& operator=(const MySingleton&) = delete;
    
    public:
    	int myInt;
    };
    
    // .cpp Nutzung Stelle A
    
    void foo() {
        MySingleton::getInstance().setInt(1);
        int test = MySingleton::getInstance().getInt();
    }
    
    // .cpp Nutzung Stelle B
    
    void bar() {
        int test = MySingleton::getInstance().getInt();
    }
    

    Da du auch Thread-Safety geschrieben hast ist dann der nächste Punkt: myInt sollte vermutlich nicht public sein. Sonst kann MySingleton nicht verhindern dass direkt zugegriffen wird -- und damit kann MySingleton z.B. auch kein Locking/Synchronisierung beim Zugriff implementieren.

    Davon abgesehen sieht das OK aus. Also kann man so machen. Die Frage ist ob die Klasse MySingleton wirklich auf die Verwendung aus Singleton eingeschränkt werden soll. Für automatisierte Tests der Klasse selbst ist es meist besser wenn man "einfach so" Objekte erzeugen kann.

    Und zuletzt natürlich: überleg dir ob du wirklich ein Singleton brauchst bzw. verwenden solltest. Für viele Sachen ist es zwar praktisch. Aber oft verschlechtert man mit Singletons die Testbarkeit von Code der das Singleton verwendet. Oft will man bei Tests dem getesteten Code von Aussen das Objekt unterschieben das verwendet werden soll. Wenn der Zugriff aber über einen Singleton-Getter funktioniert, dann geht das halt nicht. Bei manchen Dingen macht es vermutlich Sinn das in Kauf zu nehmen. Bei den meisten ist es aber besser sich etwas mehr Arbeit zu machen indem man die Instanz überall als Parameter rumreicht.


Anmelden zum Antworten