Problem mit statischen Klassenelementen



  • Hallo,

    Mein Ziel ist es ein relativ einfaches Kontrollproblem mit enorm vielen Zugriffen möglichst effizient zu lösen.

    Meine Vorstellung der objektorientierten Lösung sah so aus:

    - die Kontrollklasse besitzt nur statische Elemente
    - der function overhead der statischen Methoden sollten mittels inline reduziert werden

    Also habe ich es wie folgt versucht zu implementieren:

    Kontrollklasse.h

    class Kontrollklasse
    {
    	private:
    
    		static int Variable;
    
    	public:
    
    		Kontrollklasse() {}
    		~Kontrollklasse() {}
    
    		static void setzeKontrollvariable(int Wert);
    };
    

    Kontrollklasse.cpp

    inline void Kontrollklasse::setzeKontrollvariable(int Wert)
    {
    	Variable = Wert;
    }
    

    Nutzer.cpp

    #include „Kontrollklasse.h“
    …
    	Kontrollklasse::setzeKontrollvariable(1);
    	…
    

    Der Linker bleibt an verschiedenen Punkten wegen Gültigbereichsproblemen hängen.

    Ist das Problem mit dem Ansatz so überhaupt zu lösen?

    Vielen Dank für Eure Hilfe!



  • Sieht für mich relativ sinnlos aus, allerdings hast du auch nicht gerade viele Informationen gegeben.

    Was die Linkfehler betrifft, die inline Definition deiner Funktion muß im Header stehen.



  • Was soll daran nicht sinnvoll sein? Natürlich soll die Klasse weitere Funktionalität beinhalten.
    Wie sonst sollte ich das genannte Problem effizient lösen?

    Um das Problem etwas einzuschränken:

    Kontrollklasse.h

    class Kontrollklasse
    {
    	private:
    
    		static int Variable;
    
    	public:
    
    		Kontrollklasse() {}
    		~Kontrollklasse() {}
    
    		static void setzeKontrollvariable(int Wert)
    		{
    			Kontrollklasse::Variable = Wert;
    		}
    };
    

    Nutzer.cpp

    #include „Kontrollklasse.h“
    …
    	Kontrollklasse::setzeKontrollvariable(1);
    	…
    

    Auch hier meldet der Linker einen Fehler.
    Er kann in Nutzer.obj private: static int oglMesh::test nicht auflösen.



  • Letzte Zeile sollte heißen:

    Er kann in Nutzer.obj das Symbol "private: static int Kontrollklasse::Variable" nicht auflösen.



  • Du mußt die Variable auch noch definieren, im Header steht nur die Deklaration.

    Einfach

    int KontrollKlasse::Variable;

    in die cpp-Datei rein.



  • Wenn du innerhalb der Klasse
    static int Variable;
    definierst musst du das ausserhalb der Klasse im globalen Bereich nochmal definieren, ohne static aber mit Klassenname.
    int Kontrollklasse::Variable;



  • Aha! Prima!
    Wusste nicht dass diese auch noch definiert werden musste.

    Aber noch einmal zum Klassenentwurf, da gesagt wurde dass dies nicht sinnvoll sei.
    Mir fällt einfach keine bessere Alternative ein.
    Ein Singleton währe doch unnötig.
    Oder übersehe ich da etwas?

    Vielen Dank!



  • Jester schrieb:

    Du mußt die Variable auch noch definieren, im Header steht nur die Deklaration.

    Definition und Deklaration sind bei int Variablen das Gleiche. In der Klasse steht auch eine Definition.



  • freak11 schrieb:

    Jester schrieb:

    Du mußt die Variable auch noch definieren, im Header steht nur die Deklaration.

    Definition und Deklaration sind bei int Variablen das Gleiche. In der Klasse steht auch eine Definition.

    Eine Definition reserviert auch den benötigten Speicher.

    extern int x; ist übrigens eine Deklaration und keine Definition. Es ist ergo nicht das gleiche.



  • Eine "Klasse" die ausschliesslich aus statischen Daten-Members und statischen Memberfunktionen besteht ist IMHO keine Klasse sondern eine Abschäulichkeit. Dazu gibt es seit Annbeginn der Zeit Funktionen. Pack sie in einen Namespace und gut.

    Dein Ansatz hat im Übrigen auch mit Objektorientierung IMO nichts zu tun.



  • hustbaer schrieb:

    Eine "Klasse" die ausschliesslich aus statischen Daten-Members und statischen Memberfunktionen besteht ist IMHO keine Klasse sondern eine Abschäulichkeit. Dazu gibt es seit Annbeginn der Zeit Funktionen. Pack sie in einen Namespace und gut.

    Dein Ansatz hat im Übrigen auch mit Objektorientierung IMO nichts zu tun.

    ..und ein Singleton scheint mir durchaus Sinnvoll in dieser Situation.
    Du nennst die Klasse ja schon "Kontrollklasse", - wie oft sieht man ein "...Manager" als Klassennamen für Signeltons?

    Was genau hast du mit deinem Konstrukt eigentlich vor? Wenn es sich, wie der Name andeutet, um eine Verwalterklasse oder eine Fassade handeln sollte, sprich einfach einer Klasse mit nur einer Instanz UND einem globalen Zugriffspunkt, dann ist das Singleton Pattern miho das richtige für dich.

    Aber ich bin gespannt was du noch vor hast mit der Klasse..



  • Nun, den Ansatz mit den statischen Daten gibt es ja schon. Siehe Monostate bzw. Borg-Pattern
    und hier
    http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=147&rl=1



  • Mir ist durchaus bewusst dass dies kein "richtiges" objektorientiertes Klassenmodell ist, sondern nur eine Art Namespace-Kapselung mit privaten Datenelementen.

    Ein Singleton ist meiner Meinung nach absolut unnötig, da jedes Objekt sowieso die gleichen Daten beinhaltet.
    Ich rufe die Methoden (oder korrekter gesagt Funktionen) der Klasse mehrere hundert Tausend Mal pro Sekunde auf.
    Da spielt es schon eine Rolle dass die Zugriffsmethoden eines Singletons mit Instanzvariablen nicht inlined sein können und ich jedes Mal den this-Zeiger der Singleton-Instanz holen muss.

    Meint ihr dass dies nicht Grund genug ist, und man auch in diesem speziellen Fall konsequent objektorientiert vorgehen soll?

    Vielen Dank für Eure Ratschläge!



  • Achja, die Deklaration und Definition des Konstruktors und Destruktors wie im Beispiel gezeigt ist natürlich unnötig, da eh keine Instanzen erzeugt werden sollten.



  • Senfgurke schrieb:

    Mir ist durchaus bewusst dass dies kein "richtiges" objektorientiertes Klassenmodell ist, sondern nur eine Art Namespace-Kapselung mit privaten Datenelementen.

    Wieso nimmst du nicht gleich einen Namespace dafür, anstatt eine class zweckzuentfremden?



  • CStoll schrieb:

    Wieso nimmst du nicht gleich einen Namespace dafür, anstatt eine class zweckzuentfremden?

    Weil ich die Klassenvariablen als private deklarieren kann.



  • Wenn's dir nur um die Datenkapselung geht, kannst du die Variablen auch hinter einem anonymen Namensraum verstecken.



  • CStoll schrieb:

    Wenn's dir nur um die Datenkapselung geht, kannst du die Variablen auch hinter einem anonymen Namensraum verstecken.

    Fu.h

    namespace Fu
    {
    	inline void bar();
    }
    

    Fu.cpp

    namespace
    {
    	int privat;
    }
    
    void Fu::bar()
    {
    	privat = 0;
    }
    

    Nutzer.cpp

    #include "Fu.h"
    	...
    	Fu::bar();
    	...
    

    Da kann der Linker die Funktion nicht auflösen.
    Ohne inline-Deklaration kann er es.



  • Hmm, hat jemand eine Idee warum der Linker da Probleme hat?



  • Auch wenn ich int privat in der .cpp auserhalb des anonymen Namensbereich deklariere und definiere kann der Linker die Funktion nicht auflösen.
    Hmm...


Log in to reply