privater Destruktor



  • Jetzt hab ich aber noch ein Problem:
    Ich habe mir überlegt, dass man eine Basisklasse entwickeln könnte, deren Subklassen auch nur aufm Heap erzeugt werden können. Dazu müsste man aber den Destruktor private und nicht virtuell machen, wodurch man u.U. ein Speicherloch hätte. Wie kann ich eine derartige Basisklasse, ohne Speicherloch machen?

    thx



  • Ok. jetzt hab ich ne Lösung, und die ist so einfach, da hätte man sofort drauf kommen können, hier meine Oberklassen für Objekte, die nur aufm Heap bzw. nur aufm Stack erzeugt werden können:

    template <bool OnlyOnTheHEAP> class Base;	
    
    template <> class Base<true>
    {
    protected:
            virtual void del(){}
    private:
    	~Base(){del();}
    public:
    	Base(){}
    	void destroy(){delete this;}
    };
    
    template <> class Base<false>
    {
    public:
    	Base();
    	virtual ~Base();
    private:
    	static void* operator new(size_t size){}
    	static void operator delete(void* rawmemory){}
    	static void* operator new[](size_t size){}
    	static void operator delete[](void* rawmemory){}
    };
    

    mfg
    Glamdring



  • Hast du's getestet?

    MfG MAV



  • jo, net besonders ausführlich, aber es geht.

    mfg



  • geht doch nicht, wenn ich ne KLase von Base<true> ableite, aber nicht instanziiere gibts dennoch nen Fehler. Das iast doof, aber ich arbeite dran.

    mfg



  • Das ist mein Code:

    template <bool OnlyOnTheHEAP> class Base;   
    
    template <> class Base<true>
    {
    protected:
        virtual void del(){}
    private:
        inline ~Base(){del();}
    public:
        Base(){}
        void destroy(){delete this;}
    };
    
    template <> class Base<false>
    {
    public:
        Base();
        virtual ~Base();
    private:
        static void* operator new(size_t size){}
        static void operator delete(void* rawmemory){}
        static void* operator new[](size_t size){}
        static void operator delete[](void* rawmemory){}
    };
    
    class test : public Base<true>
    {};
    
    int main()
    {
        return 0;
    }
    

    Dieser Code wird von VC++ fehlerfrei compiliert.

    Wenn ich jetzt aber bei test einen Destruktor einfüge, der nichts macht, dann gibts nenn Fehler???

    thx
    Glamdring



  • Hab jetzt nochwas gefunden:

    #include <iostream>
    using namespace std;
    
    template <bool OnlyOnTheHEAP> class Base;   
    
    template <> class Base<true>
    {
    protected:
        virtual void del(){cout << "del von Base" << endl;}
    private:
        ~Base(){del();}
    public:
        Base(){}
        void destroy(){delete this;}
    };
    
    template <> class Base<false>
    {
    public:
        Base();
        virtual ~Base();
    private:
        static void* operator new(size_t size){}
        static void operator delete(void* rawmemory){}
        static void* operator new[](size_t size){}
        static void operator delete[](void* rawmemory){}
    };
    
    class test : public Base<true>
    {
    public:
    	void del(){cout << "del von test" << endl;}
    };
    
    int main()
    {
    	test* user = new test;
    	delete user;
            return 0;
    }
    

    Er compiliert es fehlerfrei, aber am Ende wird nichts ausgegeben.

    ???



  • Auf dem BcB funktioniert das Definitiv nicht

    kann ja auch nicht 😉
    [was hier stand war schrott der eh nur das ausdrückte was jeder weis]



  • läuft auf keinem Compiler, daran arbeite ich gerade

    Ich bin auch schon einen Schritt weiter, ich hab den Destruktor protected aber weiterhin nicht virtuell gemacht, das Problem jetzt: es wird nur del von Base aufgerufen.

    mfg
    Glamdring



  • soweit war ich gestern auch schon.
    wenn du den destruktor in base protectest und an test weitervererbst funktioniert

    test Test;
    

    wieder.
    wenn du aber in test die gleiche struktur wie in base machst, und test dann nochmal vererbst, ja richtig dann muss die abgeleitete klasse von test wieder die struktur haben.
    also sinnlos.
    ich erklär mir das so, dass zuerst der dtor der abgeleiteten klasse aufgerufen wird, der danach den dtor der basisklasse aufruft.
    da der dtor der abgeleiteten Klasse eine methode ist, kann er auf die private elemente und somit auf den vererbten protected dtor der Basisklasse zugreifen.



  • So gehts(auch mitm BCBX):

    template <bool OnlyOnTheHEAP> class Base;
    
    template <> class Base<true>
    {
    protected:
        virtual inline void del(){cout << "del von Base" << endl;}
        inline ~Base(){}
    public:
        Base(){}
        virtual void destroy(){del(); delete this;}
    };
    
    template <> class Base<false>
    {
    public:
        Base();
        virtual ~Base();
    private:
        static void* operator new(size_t size){return 0;}
        static void operator delete(void* rawmemory){}
        static void* operator new[](size_t size){return 0;}
        static void operator delete[](void* rawmemory){}
    };
    

    Dann kann man das hier machen:

    class test : public Base<true>
    {
    public:
        virtual void del(){cout << "del von test" << endl;}
    };
    
    class undertest : public test
    {
    public:
        virtual void del(){cout << "del von undertest" << endl;}
    };
    

    Dann das hier:

    int main()
    {
        undertest* user = new undertest;
        user->destroy();
        return 0;
    }
    

    Und es wird del con undertest ausgegeben.

    thx@all

    mfg



  • haste getestet ob undertest user; funktioniert?

    habs ma fix aufm bcb6.0 getestet:
    undertest user;/funzt->schlecht
    test user;//funzt->schlecht
    Base<true> user//funzt nicht->juhu^^

    //ausserdem is es klar dass del() bei dir ausgegeben wird, immerhin haste es ja als virtual deklariert



  • sry, dann muss ich nochmal ausführlich testen, aber wenn du den Destruktor von Base<true> wieder private machst gehts.

    sry



  • @glamdrink hmm was du meinen? bei base<true> läuft doch alles wie geplant?



  • aber bei den Subklassen net. Das Problem scheint zu sein, wenn die Subklassen einen Destruktor deklarieren (was sie ja nicht müssen) dann gehts scheinbar net.

    mfg



  • jede Klasse hat einen und braucht einen dtor.
    sogar bei delete this wird der dtor der Klasse aufgerufen



  • Schon klar, aber wenn ich den Destruktor nicvht definiere wird er vom Compiler erzeugt, dass ist scxheinbar OK. Aber wenn ich einen Destruktor definiere oder deklariere gibts aus irgendeinem zugegeben merkwürdigem Grund nen Fehler.

    mfg



  • öhm klappt doch..

    template <bool OnlyOnTheHEAP> class Base;
    
    template <> class Base<true>
    {
    protected:
        ~Base(){}
    public:
        Base(){}
        virtual void destroy(){delete this;}
    };
    
    class test : public Base<true>
    {
        private:
            ~test(){};
    };
    
    int main(int argc, char* argv[])
    {
        test* Test=new test;
        Test->destroy();
        return 0;
    }
    


  • es geht im obigen Post um die SUBKLASSSEN.



  • ist test keine SUBklasse?


Anmelden zum Antworten