ableiten verhindern



  • Hatte eben wieder mal ne 'was ist besser' diskussion mit nem kollegen... und dabei kam was auf was mir keine Ruhe mehr lässt.. 🤡

    Kann ich in C++ vererbung verhindern? Also so was wie final in java?
    Mir ist spontan so ein konstrukt eingefallen:

    class Foo1
    {
       Foo1() {};
       ~Foo1() {};
    
    public:
       static Foo1* Create() { 
    	return new Foo1; 
       };
       void Release() {
    	delete this;
       };
    };
    

    Jemand ne andere/besser idee? 🤡



  • CMatt schrieb:

    Jemand ne andere/besser idee? 🤡

    template<typename T>
    class Footable
    {
    
    protected://edit
    
    	Footable(){}
    	Footable(const &Footable){}
    	~Footable(){}
    public:
    
    	static T* Create() 
    	{ 
    		return new T; 
    	}; 
    
    	void Release() 
    	{
    		delete static_cast<T*>(this); 
    	}; 
    };
    
    class Foo : public Footable<Foo>
    {
    	...
    };
    


  • ssm schrieb:

    CMatt schrieb:

    Jemand ne andere/besser idee? 🤡

    template<typename T>
    class Footable
    {
    
    protected://edit
    
    	Footable(){}
    	Footable(const &Footable){}
    	~Footable(){}
    public:
    
    	static T* Create() 
    	{ 
    		return new T; 
    	}; 
    
    	void Release() 
    	{
    		delete static_cast<T*>(this); 
    	}; 
    };
    
    class Foo : public Footable<Foo>
    {
    	...
    };
    

    hmm.. mal abgesehen davon das dein copy-constructor nicht wirklich brauchbar ist, geht es mir darum das ableiten von Foo zu verhindern, nicht das Create/Release zeug in ein template zu stopfen 🤡



  • Ueber dieses Thema laesst sich Scott Meyers in "More Effective
    C++" recht ausfuehrlich aus. Leider habe ich ihn hier nicht zur
    Hand, deshalb sind meiner Ausfuehrungen mit Vorsicht zu geniessen:

    Man definiert die eigentlichen Konstruktoren privat und stellt
    stattdessen "Pseudo-Konstruktoren" zur Verfuegung, die intern
    die echten Konstruktoren aufrufen:

    class C {
     private:
      C();
      C(const C&);
     public:
      static C* default_constr() { return new C; }
      static C* copy_constr(const C& rhs) { return new C(rhs); }
      //...
     };
    

    Ableiten ist nun nicht mehr moeglich, da jeder Konstruktor
    einer Instanz der abgeleiteten Klasse als erstes den
    Basisteil initialisieren muss -- also irgendeinen Konstruktor von C
    aufrufen muss. Ein Objekt der Klasse C laesst sich aber wie folgt
    instanzieren:

    void f()
     {
      C* pc1 = C::default_constr();
      C* pc2 = C::copy_constr(*pc1);
     }
    

    Das ist nicht besonders schoen. Ausserdem werden so keine Objekte
    auf dem Stack abgelegt. Dies laesst sich aber emulieren durch die
    Verwendung von Auto-Pointern. In jedem Fall aber tut es das, was
    Du willst.

    Gruss,
    Michael




Log in to reply