Doppeldeutigkeit nach mehrfachvererbung



  • ...



  • ----------------------------------------------------------------------------------------------------------------------------------------------------------------
    Regel Nr.1 für die Anwendung von Singletons: Niemals von Singletons ableiten !!!
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------

    Egal was man auch immer für eine Klasse, für was auch immer für einen Anwendungsfall hat.
    Die Bedingung nur eine Instanz davon zu erlauben ist kontextabhängig und hat in allen Fällen nichts mit der Klasse selbst zu tun.

    class c
    {
     // aus bequemlichkeit innerhalb der klasse realisiert
     c* instance() 
     { 
        return singleton<c>::instance(); 
     }
    }
    

    Das Singleton Interface kann auch total außerhalb der Klasse sein.

    // freie funktion
    c* single_instance()
    { 
      return singleton<c>::instance();
    }
    

    Merke: Siehst du eine Klasse, die von einem Singleton erbt, hat es ein Anfänger programmiert.



  • Merke: Siehst du eine Klasse, die von einem Singleton erbt, hat es ein Anfänger programmiert.

    Wenn das stimmen sollte, gibt es auch Anfänger mit mehreren Jahren Berufserfahrung. 🤡



  • Merke: Siehst du eine Klasse, die von einem Singleton erbt, hat es ein Anfänger programmiert.

    ähäm, wenn du meinst Andrei Alexandrescu wäre ein anfänger... dann gibt es aber sehr wenig profis 😃

    Aber deine idee mit dem auslagern ist super. dann kann ich auf die ganzen lösungsvorschläge von diesem diamond-problem ablassen 💡
    allerdings hab ich noch eine frage, wenn ich das singleton so verwende wie du es als beispiel angegeben hast kann ich die klasse einfach kopieren?
    das heißt ich müsste dann kopierkonstrukoren und operatoren noch private machen.
    Naja, ich folge mal diesem ansatz, der scheint mir sinnvoll 🙂



  • Andrei Alexandrescu ist sowieso ein Verräter, da er zu D gewechselt ist.



  • Andrei Alexandrescu ist sowieso ein Verräter, da er zu D gewechselt ist.

    😃
    er ist nicht nur dazu gewechselt, er entwickelt die sprache mit.
    Das heißt aber noch lange nicht, das er C++ nicht drauf hat, ich finde seine bücher genial.



  • gamer8o4 schrieb:

    ähäm, wenn du meinst Andrei Alexandrescu wäre ein anfänger... dann gibt es aber sehr wenig profis 😃

    Alexandrescus Leistung an der Stelle war, dass er gezeigt hat, was alles mit templates möglich ist. Aber das wichtigste was man aus dem Kapitel hätte mitnehmen müssen ist: Singletons sind absoluter scheissendreck der an allen möglichen Stellen mit dem Sprachstandard kollidiert und mehr Probleme schafft, als er löst. Das ganze Kapitel mit all den Veränderungen ist doch ein gigantisches "tut das nicht!". Warum tust du es trotzdem?



  • gamer8o4 schrieb:

    Das heißt aber noch lange nicht, das er C++ nicht drauf hat, ich finde seine bücher genial.

    Sie lesen sich unglaublich nett.
    Muss aber zugeben, daß ich aus seinen Büchern nur genommen habe, daß ich seitdem wesentlich besser templierern kann. Die Extreme in den Büchern aber sind nicht sachdienlich in der Praxis, soweit ich sehe. Das wertet dir Bücher nicht ab. Hätte er bescheiden templiert, wäre ich noch auf der Suche nach Grenzen. Tag für Tag. Er hat mir 50 Jahre zu forschen erspart in beiden Richtungen, was ich mehr und was ich weniger templieren sollte.
    👍 👍 👍 Andrei Alexandrescu 👍 👍 👍



  • Also, das ich mich noch einmal rechtfertigen darf bitte:

    Im original code habe ich zwei klassen die beide die klasse
    CDefaultThreadingModel erben.
    nun will ich eine dritte klasse erstellen, welche sich von den beiden ersten klassen ableitet, aber habe natürlich das problem, dass die member von CDefaultThreadingModel doppelt existieren

    Ich habe den Code gar nicht angeschaut. Nach diesem Satz schien mir klar, wo das Problem lag.
    Das der TE das falsch beschrieben hatte kam mir doch nicht in den Sinn...



  • gamer8o4 schrieb:

    also so sieht mein grundgerüst aus:
    (eine abgewandelte version von dem singleton von andrei alexandrescu)

    // CSingleton
    	// -> this class is a very variable implementation of the Singleton design pattern descriped by the GoF
    	//    "Ensure a class only has one instance, and provide a global point of access to it."
    	template<
    		class T,
    		template<class> class TLifetime = DELTA_CORE_SINGLETON_LIFETIME_DEFAULT,
    		template<class> class TAlloc = DELTA_CORE_ALLOCATOR_DEFAULT,
    		template<class,class> class TThreadingModel = DELTA_CORE_THREAD_MODEL_CLASSLEVEL,
    		class TMutex = DELTA_CORE_THREAD_MUTEX_DEFAULT
    	>
    	class CSingleton{
    	public:
    		typedef T obj_type; // type of the singleton object
    
    		static obj_type& getInstance();
    
        private:
            // Helpers
            static void createSingleton();
            static void destroySingleton();
            
            // Protection
            CSingleton();
    		CSingleton(const CSingleton&);
    		CSingleton& operator=(const CSingleton&);
    		~CSingleton();
            
            // Data
            typedef typename TThreadingModel<T*,TMutex>::volatile_type ptr_instance_type;
            static ptr_instance_type m_instance;
            static bool m_destroyed;
    	};
    
    class c : public CSingleton<c>{
    
    };
    

    Also

    template<typename T,typename TM>
    class Sigleton{
       static T& getInstande();
       TM threadingModel;
    };
    class Drucker:public Singleton<Drucker,ThreadingModelSingleThreaded>{
    };
    class Monitor:public Singleton<Monitor,MultiThreadedDFBSD>{
    };
    class AB:public Drucker,public Monitor{
    };
    

    Und immer noch ist da keine Raute des Todes.

    Natürlich geht

    AB ab;
    ab.getInstance();//wollte ich Drucker oder Monitor haben? 
    ab.getInstance().threadingModel;//wollte ich vom Drucker oder vom Monitor dem sein ThreadinModel haben?
    

    nicht. Das ist aber aus C++-Sicht nicht rautig (voll pöse), sondern bloß ambig (leicht unbequem). Aber es ist inhaltlich nicht auflösbar als Folge eines Designfehlers, fürchte ich.

    class AB:public Drucker,public Monitor{
       void lock(){
          this->Drucker::lock();
          this->Monitor::lock();
       }
    };
    

    Nicht gut.

    Also doch die Raute des Todes bauen. Klar.

    template<typename T,typename TM>
    class Sigleton:publich TM{
       static T& getInstande();
    };
    templateytypename TM>
    class Drucker:virtual public Singleton<Drucker,TM>{
    };
    templateytypename TM>
    class Monitor:virtual public Singleton<Monitor,TM>{
    };
    template<typename TM>
    class AB:public Drucker<TM>,public Monitor<TM>{
    };
    

    Klar. Helau. 🤡 🤡 🤡
    War eigentlich ganz einfach. Man muß sich nur immer von einem kleinen Designfehler in den nächst größeren treiben lassen. Tag für Tag. Das macht Spaß.



  • So ganz verstehe ich deinen Beitrag nicht volkard, was hat AB mit Druckern und Monitoren zu tun. Oder anders gefragt, wenn du Drucker, Monitore und das Singleton definierst, wo kommt dann dein A und dein B her?



  • Skym0sh0 schrieb:

    So ganz verstehe ich deinen Beitrag nicht volkard, was hat AB mit Druckern und Monitoren zu tun. Oder anders gefragt, wenn du Drucker, Monitore und das Singleton definierst, wo kommt dann dein A und dein B her?

    Sorry, Copy&Paste-Fehler. A:=Drucker, B:=Monitor.


Anmelden zum Antworten