Statische Klassen



  • Hallo zusammen,

    leider half mir die Forumssuche hier bisher nicht weiter.

    Habe folgendes Problem:

    Habe eine Klasse, die nur aus statischen Methoden besteht (dazu noch Konstruktor und Destruktor).

    Nun hab ich im Headerfile alles statisch deklariert, auch die Membervariable, der GCC meckert mir aber an, dass in meinem Implmentierungsfile die Methoden außerhalb der Klasse stehen!?

    Versteh ich nicht!

    Hier mal Bsp.-Code dieser Klasse:

    Header:

    ...
    class FrameFactoryC
    {
     public:
            static void createAddFrame(...);
            static const std::vector<FrameC *> &getFrames(const int type);
    
     private:
            static std::map<const int, std::vector<FrameC *> > frames;
            FrameFactoryC();
            ~FrameFactoryC();
            FrameFactoryC(const FrameFactoryC&);
            void operator=(const FrameFactoryC&);;
    };
    #endif
    

    Implementierung:

    ...
    void FrameFactoryC::createAddFrame(...)
    {
    ...
    }
    
    std::vector<FrameC *> &getFrames(const int type)
    {
    ...
    }
    

    Fehlermeldung:

    error: declaration of `static void 
       FrameFactoryC::createAddFrame(...)' outside of class is not definition
    

    Was stimmt damit nicht? Wieso Deklaration? Die ist doch im Header?
    Das einzige, was ich wegnehmen musste (wie bei anderen Klassen auch) waren die
    Defaultargumente! Die will der GCC nur im Headerfile haben, nicht in der Implementierung!

    Und wird der Destruktor überhaupt gerufen, wenn doch alles statisch ist?
    Oder muss ich mir selbst ein Objekt des Typs dieser Klasse zur Laufzeit anlegen?

    Ciao



  • http://www.c-plusplus.net/forum/viewtopic-var-p-is-1297057.html#1297057 ⚠

    Meine Glaskugel sagt mir dass du nach dem Copy & Paste vergessen hast das Semikolon zu löschen.



  • eine klasse aus nur statischen methoden ohne Attribute braucht kein konstruktor oder destruktor, der Automatisch vergebene reicht da vollkommen aus. Allerdings ist es sowiso sinnlos sowas zu erstellen, erstell lieber mal ein namespace und packe da deine Methoden als einfache Funktionen rein, dann sind sich auch schön verpackt (C++ ist nicht Java).



  • @finix:

    Tolle Kugel hast Du da! 😃
    Wo gibs die denn? Will auch eine!

    Krux schrieb:

    eine klasse aus nur statischen methoden ohne Attribute braucht kein konstruktor oder destruktor, der Automatisch vergebene reicht da vollkommen aus. Allerdings ist es sowiso sinnlos sowas zu erstellen, erstell lieber mal ein namespace und packe da deine Methoden als einfache Funktionen rein, dann sind sich auch schön verpackt (C++ ist nicht Java).

    Das stimmt schon!
    Aber ich sehe da keinen so großen Unterschied, da eine Klasse an sich doch auch schon einen Namespace liefert, wenn sie nur aus statischen Methoden besteht!?

    Ist das gängige Praxis in C++, dass wenn man nur statische Dinge hat man diese in nen Namespace packt anstatt in eine Klasse?

    Wie macht man das dann mit Zugriffschutz? In ner Klasse mit nur statischen Methoden kann ich immerhin noch private Member anlegen, die nur über diese Methoden zugreifbar sind!

    Aber wie initialisiere ich so ein privates Member dann (z.B. nen STL-Vector)?

    Ciao



  • Jetzt hab ich dazu noch eine Frage:

    Ich bekomme beim Linken lauter undefined References angezeigt.
    Einige davon in den statischen Klasse, denke mal, dass es evtl. an der fehlenden Initialisierung der Membervariablen (ebenfalls statisch) liegt, oder aber an deren Verwendung!?

    Bei den anderen undefined references weiss ich auch noch nicht, was los ist!

    Hier mal die Klasse, in der u.a. dieses bemängelt wird:

    Header:

    #ifndef FRAMEFACTORY_H
    #define FRAMEFACTORY_H
    
    #include <map>
    #include <iostream>
    #include <vector>
    #include <time.h>
    #include "FrameC.h"
    
    class FrameFactoryC
    {
     public:
            static void createAddFrame(const int type, int width, int height, PLANEPTR data, PLANEPTR mask=NULL, const struct BitMap * const friendBitMap=NULL);
            static const std::vector<FrameC *> &getFrames(const int type);
    
     private:
            static std::map<const int, std::vector<FrameC *> > frames;
    
            FrameFactoryC();
            ~FrameFactoryC();
            FrameFactoryC(const FrameFactoryC&);
            void operator=(const FrameFactoryC&);
    };
    #endif
    

    Implementierung:

    #include "FrameFactoryC.h"
    
    FrameFactoryC::FrameFactoryC()
    {
    }
    
    FrameFactoryC::~FrameFactoryC()
    {
        for (std::map<const int, std::vector<FrameC *> >::iterator iter = frames.begin(); iter != frames.end(); iter++)
        {
            for (std::vector<FrameC *>::iterator itVec = iter->second.begin(); itVec != iter->second.end(); itVec++)
            {
                delete (*itVec);
            }        
            iter->second.clear();
        }
        frames.clear();
    }
    
    void FrameFactoryC::createAddFrame(const int type, int width, int height, PLANEPTR data, PLANEPTR mask, const struct BitMap * const friendBitMap)
    {
        FrameC *frame = new FrameC(width, height, data, mask, friendBitMap);
        frames[type].push_back(frame);
    }
    
    const std::vector<FrameC *> &FrameFactoryC::getFrames(const int type)
    {
        return frames[type];
    }
    

    Und hier die Meinung des Linkers:

    o/gcc-classic/FrameFactoryC.o(.text+0x24): undefined reference to `_ZN13FrameFactoryC6framesE'
    o/gcc-classic/FrameFactoryC.o(.text+0x36): undefined reference to `_ZN13FrameFactoryC6framesE'
    o/gcc-classic/FrameFactoryC.o(.text+0x126): undefined reference to `_ZN13FrameFactoryC6framesE'
    o/gcc-classic/FrameFactoryC.o(.text+0x148): undefined reference to `_ZN13FrameFactoryC6framesE'
    o/gcc-classic/FrameFactoryC.o(.text+0x15a): undefined reference to `_ZN13FrameFactoryC6framesE'
    o/gcc-classic/FrameFactoryC.o(.text+0x24a): more undefined references to `_ZN13FrameFactoryC6framesE' follow
    

    Soll ich noch die Ausschnitte des makefiles dazu liefern (arbeite mit GCC)?

    Kann mir da jmd. weiterhelfen?

    Vielen Dank schon einmal!

    Ciao



  • Naja, du hast es ja auch tatsächlich nirgendwo definiert. Im Prinzip sind statische Klassenmember nicht mehr als globale Variablen. Deshalb reicht auch die Deklaration nicht aus (wäre für globale Variablen sowas wie extern int bla;), sondern du musst sie noch in genau(!) einer Quellcodedatei definieren. Deine FrameFactoryC.cpp bietet sich da sehr an:

    #include "FrameFactoryC.h"
    
    // Vielleicht auch mit Konstruktorargumenten oder sowas
    std::map<const int, std::vector<FrameC *> > FrameFactoryC::frames;
    
    // der Rest
    

    ABER, es gibt einen guten Grund, so etwas nicht zu tun: Hängen mehrere solcher statischen Member voneinander ab, so kann das ganz schön in die Hose gehen, weil die Initialisierungsreihenfolge leider nicht definiert ist. Es man kann (und im Zweifel wird) also eine solche Variable vor ihrer Initialisierung verwenden.

    Besser fährst du meistens mit einem Meyers-Singleton:

    class Factory
    {
    public:
        static Factory& instance ()
        {
            static Factory* _instance = 0;
            if (!_instance) _instance = new Factory;
            return &_instance;
        }
    
    private:
        Factory ();
        // kopieren noch verhindern
    };
    

    Ansonsten wird die Klasse implementiert wie eine normale Klasse. Das hat in etwa denselben Effekt, ist aber zumindest was die Initialisierung angeht sicherer (aber nicht thread-safe!), die einzige Instanz der Klasse wird mit dem ersten Aufruf von Factory::instance() angelegt.



  • bababab

    #if !defined(FRAMEFACTORY_H__INCLUDED)
    #define FRAMEFACTORY_H__INCLUDED
    
    #if (_MSC_VER > 1000)
    	#pragma once
    #endif // (_MSC_VER > 1000)
    
    #include <map>
    #include <vector>
    #include <ctime>
    #include "FrameC.h"
    
    class FrameFactoryC
    {
    private:
    	FrameFactoryC();
    	~FrameFactoryC()
    	{
    		for (std::map<const unsigned int, std::vector<FrameC*> >::iterator it = m_frames.begin(); it != m_frames.end(); ++it)
    		{
    			for (std::vector<FrameC *>::iterator it_vec = it->second.begin(); it_vec != it->second.end(); ++it_vec)
    				delete (*it_vec);
    
    			it->second.clear();
    		}
    	    m_frames.clear();
        }
    
    	FrameFactoryC(const FrameFactoryC&);
    	operator= (const FrameFactoryC&);
    
    public:
    	static FrameFactoryC& instance() { static FrameFactoryC inst; return inst; }
    
    public:
    	void add_new_frame(const unsigned int, const unsigned int, const unsigned int, PLANEPTR, PLANEPTR mask = NULL, const BitMap * const friendBitMap = NULL)
    	{ m_frames[type] = m_frames.push_back(new FrameC(width, height, data, mask, friendBitMap));	}
    	std::vector<FrameC*>& getFrames(const unsigned int type) const	{ return m_frames[type]; }
    
    private:
    	std::map<const unsigned int, std::vector<FrameC*> >		m_frames;
    };
    
    #endif // FRAMEFACTORY_H__INCLUDED
    

    ...



  • Reth schrieb:

    ...
    Aber ich sehe da keinen so großen Unterschied, da eine Klasse an sich doch auch schon einen Namespace liefert, wenn sie nur aus statischen Methoden besteht!?

    Ist das gängige Praxis in C++, dass wenn man nur statische Dinge hat man diese in nen Namespace packt anstatt in eine Klasse?...

    Der Vorteil ist, dass man in einem namespace weniger "Verwirrungspotential" hat. Man kommt nicht in Versuchung, eine Instanz anzulegen oder abzuleiten oder Anderes zu tun, wofür eine "reine Fuktionssammlung" nicht ausgelegt ist.

    Reth schrieb:

    ...
    Wie macht man das dann mit Zugriffschutz? In ner Klasse mit nur statischen Methoden kann ich immerhin noch private Member anlegen, die nur über diese Methoden zugreifbar sind!...

    Eigentlich ist der "Zugriffschutz" entworfen worden zur Kapselung von Daten ... und solche hast Du in diesem Fall gar nicht.
    Wenn Du zwischen "externen" und "Hilfsfunktionen" unterscheiden (oder eine konkrete Implementierung verstecken) willst, bietet sich da die "klassische Modularisierung" viel eher an:

    // meineFunktionen.h
    namespace meineFunktionen {
       int f(int);
       int g(int);
    }
    
    // meineFunktionen.cpp
    #include "meineFunktionen.h"
    
    namespace { // anonymer namespace
       int Hilfsfunktion1(int a) { return a+3; }
       int Hilfsfunktion2(int a) { return a+5; }
    }
    // Implementation
    namespace meineFunktionen {
       int f(int x) { return Hilfsfunktion1(x*2); }
       int g(int x) { return Hilfsfunktion2(x*3); }
    }
    

    Da kannst Du sogar Hilfsfunktionen zufügen/Namen ändern/..., ohne dass ein Benutzer von f() und g() neu compilieren müsste. Und für statische Variablen geht das genauso.

    Reth schrieb:

    ...
    Aber wie initialisiere ich so ein privates Member dann (z.B. nen STL-Vector)?
    Ciao

    Ein privates Mamber hat in einer Klasse mit nur statischen Funktionen keinen Sinn, weil Du gar keinen Zugriff darauf hast (wenn Du nur statische Funktionen hast).

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Reth schrieb:

    ...
    Der Vorteil ist, dass man in einem namespace weniger "Verwirrungspotential" hat. Man kommt nicht in Versuchung, eine Instanz anzulegen oder abzuleiten oder Anderes zu tun, wofür eine "reine Fuktionssammlung" nicht ausgelegt ist.

    Dazu habe ich den Konstruktor private gemacht.

    Eigentlich ist der "Zugriffschutz" entworfen worden zur Kapselung von Daten ... und solche hast Du in diesem Fall gar nicht.
    Wenn Du zwischen "externen" und "Hilfsfunktionen" unterscheiden (oder eine konkrete Implementierung verstecken) willst, bietet sich da die "klassische Modularisierung" viel eher an:

    // meineFunktionen.h
    namespace meineFunktionen {
       int f(int);
       int g(int);
    }
    
    // meineFunktionen.cpp
    #include "meineFunktionen.h"
    
    namespace { // anonymer namespace
       int Hilfsfunktion1(int a) { return a+3; }
       int Hilfsfunktion2(int a) { return a+5; }
    }
    // Implementation
    namespace meineFunktionen {
       int f(int x) { return Hilfsfunktion1(x*2); }
       int g(int x) { return Hilfsfunktion2(x*3); }
    }
    

    Da kannst Du sogar Hilfsfunktionen zufügen/Namen ändern/..., ohne dass ein Benutzer von f() und g() neu compilieren müsste. Und für statische Variablen geht das genauso.

    Zugriffsschutz meinte ich in dem Sinne, dass ich eine private Variable in der Klasse brauche, auf die nur die Klasse Zugriff haben soll. Geht das auch mit Namespaces?

    Zudem fehlt mir bei einer Funktionssammlung irgendwie die Objektorientiertheit.

    Reth schrieb:

    ...
    Aber wie initialisiere ich so ein privates Member dann (z.B. nen STL-Vector)?
    Ciao

    Ein privates Mamber hat in einer Klasse mit nur statischen Funktionen keinen Sinn, weil Du gar keinen Zugriff darauf hast (wenn Du nur statische Funktionen hast).

    Ich denke doch, wenn denn das Member ist private und statisch.
    Mir geht es darum, dass diese Klasse alleinig für die Erzeugung, Entsorgung und Verwaltung bestimmter Objekte zuständig ist.

    Dazu würde auch ein Singleton/Factory-Ansatz funktionieren, dann hätte ich aber das Problem, dass überall dort, wo ich diese(s) Singleton/Factory benötige irgendwie eine Referenz oder einen Zeiger darauf hinbekommen muss, d.h. überall einen weiteren Übergabeparameter.

    Mit ner statischen Klasse kann ich das umgehen, die kann ich nach dem include von überall aus zugreifen!

    Vllt. kann ich später noch den Code posten.

    Ciao



  • warum einen weiteren übergabe parameter?

    //header.h
    
    class Singleton
    {
    //...
    public: Singleton& get_instance () { /* impl siehe oben */ }
    };
    
    //irgendeine_unit.cc
    void foo () //notiere: kein singleton-argument nötig
    {
      Singleton &factory = Singleton::get_instance();
      factory.create_new_blubb();
    }
    

    ach, und übrigens: nur wenn man alles in klassen packt, ist das noch lange nicht "objekt" orientiert.



  • queer_boy schrieb:

    warum einen weiteren übergabe parameter?

    //header.h
    
    class Singleton
    {
    //...
    public: Singleton& get_instance () { /* impl siehe oben */ }
    };
    
    //irgendeine_unit.cc
    void foo () //notiere: kein singleton-argument nötig
    {
      Singleton &factory = Singleton::get_instance();
      factory.create_new_blubb();
    }
    

    Gute Idee das Singleton so einzurichten, aber hat der statische Ansatz nicht noch ein paar Compile-, Memory-, usw. Vorteile?
    Und kann man nicht-statische Methoden einer Klasse (getInstance() in diesem Falle), denn so wie in foo() angegeben ohne referenzierendes Objekt aufrufen?
    Das ist mir neu!

    /* impl siehe oben */

    Hab ich was übersehen?

    ach, und übrigens: nur wenn man alles in klassen packt, ist das noch lange nicht "objekt" orientiert.

    Mir ist schon klar, dass es noch lang kein OO ist, wenn man alles in Klassen packt!

    Aber es ist keins, wenn man sich Hilfsfunktionen in Namespaces legt (naja, kommt natürlich immer auf die Betrachtungsweise an; z.B. wenn man OO nicht mit Klassen umsetzt, sondern mit anderen Ansätzen, so dass ein Namespace zu einer Einheit wird, die ein Objekt der realen Welt widerspiegelt, ums mal platt auf Vorlesungsdeutsch zu sagen - bin aber noch zu sehr C++ Anfänger, um das Beurteilen zu können)!

    Ciao



  • Reth schrieb:

    Gute Idee das Singleton so einzurichten, aber hat der statische Ansatz nicht noch ein paar Compile-, Memory-, usw. Vorteile?

    Nein. Es wird der gleiche Speicherplatz verwendet, aber dessen Initialisierung ist zu einem definierten Zeitpunkt. Die ganzen instance()-Aufrufe werden wegoptimiert.

    Reth schrieb:

    Und kann man nicht-statische Methoden einer Klasse (getInstance() in diesem Falle), denn so wie in foo() angegeben ohne referenzierendes Objekt aufrufen?
    Das ist mir neu!

    Mir auch ;). Ist ein Schreibfehler. Bei meinem Code ist das static da und es gehört auch dahin.

    Reth schrieb:

    /* impl siehe oben */

    Hab ich was übersehen?

    Du musst nirgendwo in deinem Programm irgendwelche Referenzen oder Zeiger auf das Objekt durch die Gegend reichen. Jede Funktion kommt ohne Umwege direkt über die statische instance-Methode an das (einzige!) Objekt der Klasse. Damit du nicht so viel schreiben musst, kannst du aber auch am Anfang einer Funktion, in der das Objekt häufig benötigt wird eine Referenz anlegen (wird auch wegoptimiert).

    Reth schrieb:

    ach, und übrigens: nur wenn man alles in klassen packt, ist das noch lange nicht "objekt" orientiert.

    Aber es ist keins, wenn man sich Hilfsfunktionen in Namespaces legt (naja, kommt natürlich immer auf die Betrachtungsweise an; z.B. wenn man OO nicht mit Klassen umsetzt, sondern mit anderen Ansätzen, so dass ein Namespace zu einer Einheit wird, die ein Objekt der realen Welt widerspiegelt, ums mal platt auf Vorlesungsdeutsch zu sagen - bin aber noch zu sehr C++ Anfänger, um das Beurteilen zu können)!

    [/quote]IMHO ist der einzige, akzeptable objektorientierte Ansatz das Singleton-Pattern. Der namespace-Kram macht die Kapselung kaputt, die static-Methoden haben die oben beschriebenen Probleme.



  • .filmor schrieb:

    IMHO ist der einzige, akzeptable objektorientierte Ansatz das Singleton-Pattern. Der namespace-Kram macht die Kapselung kaputt, die static-Methoden haben die oben beschriebenen Probleme.

    Ja, der Singleton-Ansatz gefällt mir auch am besten.
    Danke nochmals dafür!

    Hm, hab den Thread nochmal durchgelesen, welche beschriebenen Probleme der statischen Methoden meinst Du genau?

    Ciao



  • Reth schrieb:

    Ist das gängige Praxis in C++, dass wenn man nur statische Dinge hat man diese in nen Namespace packt anstatt in eine Klasse?

    Man sollte immer das nehmen was passt. Eine Klasse ist eine Klasse und keine "Sammlung von freien Funktionen". Freie Funktionen sollte man also als eben solche Implementieren.

    Sobald etwas allerdings Daten ("State") hat ist fast immer eine Klasse die richtige Wahl, nur sollte diese dann auch mehrfach instanzierbar sein.
    Die Erklärung warum das fast immer eine gute Idee ist, und eben ein Singleton eine schlechte Idee ist würde fürchte ich etwas lange, also glaubs mir einfach 🙂

    Die beste Lösung ist meistens explizit eine Referenz (oder Pointer oder shared_ptr) auf die zu verwendende Instanz rumzureichen. Das ist zwar etwas mehr Tippaufwand, aber sicherlich die saubrerer Lösung.

    p.S.: die Formulierung "gängige Praxis" habe ich absichtlich nicht verwendet, da in C++ leider viele "unsaubere" Praktiken "gängig" sind.



  • hustbaer schrieb:

    Sobald etwas allerdings Daten ("State") hat ist fast immer eine Klasse die richtige Wahl, nur sollte diese dann auch mehrfach instanzierbar sein.
    Die Erklärung warum das fast immer eine gute Idee ist, und eben ein Singleton eine schlechte Idee ist würde fürchte ich etwas lange, also glaubs mir einfach 🙂

    Kannst Du denn einen kurzen Tipp in diese Richtung bringen (wenn das ansonsten zu lang wird)?

    In meinem Fall ist die Klasse, die als Singleton arbeiten soll ja eine Factory, in der Objekte erzeugt, verwaltet und am Ende aufgeräumt werden sollen.
    Es handelt sich dabei um alle grafischen Objekte einer Applikation.
    Aus dem Grund denke ich, dass mehrere Instanzen dieser Factory pro Applikation unnötig sind, da alle grafischen Objekte in einer Instanz (pro Applikation) verwaltet werden sollten.

    Natürlich könnte man auch mehrere solcher Instanzen innerhalb einer Applikation erzeugen und verwenden, allerdings sehe ich da keinen Sinn drin.

    Was wären denn die Argumente für mehrere Instanzen in meinem Fall?
    (evtl. grafische Objekte pro Fenster innerhalb der Applikation? Aber z.B. eine Knopfgrafik sollte ja in versch. Fenstern verwendbar sein, ohne dass sie mehrfach im Speicher vorgehalten wird!)

    Ciao



  • .filmor schrieb:

    Besser fährst du meistens mit einem Meyers-Singleton:

    class Factory
    {
    public:
        static Factory& instance ()
        {
            static Factory* _instance = 0;
            if (!_instance) _instance = new Factory;
            return &_instance;
        }
    
    private:
        Factory ();
        // kopieren noch verhindern
    };
    

    Eine Frage dazu noch!
    Nach meinem Verständnis ist der scope von _instance doch nur die Methode instance(), oder?
    D.h. nach dem Verlassen der Methode ist dieser Zeiger undefiniert, nicht?

    Muss die Zeigervariable für die Singleton-Instanz denn kein statisches privates Klassenmember sein?

    Ciao



  • hmm das ist sicherlich nicht die normale implementierung des Meyer'schen Singletons.



  • Reth schrieb:

    Eine Frage dazu noch!
    Nach meinem Verständnis ist der scope von _instance doch nur die Methode instance(), oder?
    D.h. nach dem Verlassen der Methode ist dieser Zeiger undefiniert, nicht?

    Muss die Zeigervariable für die Singleton-Instanz denn kein statisches privates Klassenmember sein?

    Nein. Dafür ist das static innerhalb der Methode. Das hat den Effekt, dass diese Variable der Methode selbst "gehört". Der Konstruktor der Variable wird beim ersten Methodenaufruf aufgerufen und der Zeiger deshalb mit initialisiert.

    (D)Evil schrieb:

    hmm das ist sicherlich nicht die normale implementierung des Meyer'schen Singletons.

    Was ist denn die Normale? Ich dachte, das wäre sie. Man kann natürlich noch statt eines Zeigers einfach eine Variable verwenden, wenns einem Spaß macht. Aber die Essenz ist doch einfach nur, dass die Instanz in der Funktion liegt und erst erzeugt wird, wenn sie benötigt wird.



  • Reth schrieb:

    ...
    Ich denke doch, wenn denn das Member ist private und statisch....

    Das bedeutet doch wiederum nichts Anderes als was ich oben beschrieb: Eine "globale Variable für Deinen internen Gebrauch".... und da halte ich den "klassischen Ansatz" für besser, weil er stärker kapselt (also stärker als "private"):

    //meineFunktionen.cpp
    namespace { // Anonymer namespace
       int glob1 = 3; // geht genauso wie meine "Hilfsfunktionen" oben
    }
    
    namespace meineFunktionen {
       int f(int x) { return x * glob1++; }
    }
    

    Jetzt kann nicht nur niemand außerhalb Deines Moduls darauf zugreifen, sondern er sieht sie nicht mal ! Also: Keine Probleme mit Mehrdeutigkeiten, nur Linkabhängigkeit (wenn Du glob1 mal verändern willst), ....
    Ich sehe immer noch keinen Vorteil in einem privatem statischen Element in einer Klasse ... und auch nicht von einer "statischen Klasse".

    Reth schrieb:

    ...Mit ner statischen Klasse kann ich das umgehen, die kann ich nach dem include von überall aus zugreifen!...

    Aber auf Dein private Member soll doch keiner drauf zugreifen !! (sonst wäre es wohl nicht private) ... damit sehe ich nicht ein, warum es alle "sehen" sollten.

    Gruß,

    Simon2.



  • .filmor schrieb:

    (D)Evil schrieb:

    hmm das ist sicherlich nicht die normale implementierung des Meyer'schen Singletons.

    Was ist denn die Normale? Ich dachte, das wäre sie. Man kann natürlich noch statt eines Zeigers einfach eine Variable verwenden, wenns einem Spaß macht. Aber die Essenz ist doch einfach nur, dass die Instanz in der Funktion liegt und erst erzeugt wird, wenn sie benötigt wird.

    Könnte man. Spart Schreibarbeit und hat technisch fast denselben Effekt.
    Ich meine aber auch gelesen zu haben, dass das klassische Meyers-Singleton sich gerade dadurch auszeichnet, dass es die lazy-initialization von funktionslokalen statischen Variablen ausnutzt.

    static Factory& instance ()
        {
            static Factory _instance;
            return _instance;
        }
    

Anmelden zum Antworten