Virtueller Constructor



  • Hallo

    es gibt auf jeden Fall virtuelle Destruktoren.

    chrische



  • Hallo chrische5,

    Destruktoren sollten eigentlich immer virtuell sein, hab ich gehört...
    (Auf jeden Fall, wenn von der Klasse abgeleitet wird)

    Aber ne gute Frage:
    Wann brauchen Destruktoren nicht virtuell sein?
    Wenn von der Klasse nicht abgeleitet wird?

    VirtCon



  • Hallo

    Also wenn du nicht ableitest, brauchst du auch den Destruktor nicht virtuell machen.

    chrische



  • chrische5 schrieb:

    Also wenn du nicht ableitest, brauchst du auch den Destruktor nicht virtuell machen.

    Auch wenn du von einer Basisklasse ableiten möchtest, muss der Dtor nicht zwangsläufig virtuell sein. Es ist lediglich so, dass du in folgenden Konstrukten den Dtor virtuell machen musst, da alles andere undefiniert ist.

    class base { ... };
    class derived : public base { ... };
    
    int main()
    {
        base* base_ptr = new derived; // Basisklassen-Zeiger auf ein abgeleitetes Objekt.
        ...
    
        delete base_ptr; // undefiniertes Verhalten. (Meistens wird nur der Dtor der basisklasse aufgerufen).
    }
    

    Allerdings ist bei den meisten Klassen, die als Basisklassen fungieren sollen, der Dtor virtuell, damit obige Einschränkung nicht gilt.

    Gruß Caipi



  • VirtCon schrieb:

    Hallo,
    gibt es virtuelle Konstruktoren...
    Ich denke hier in erster Linie an den Copy-Constructor...

    Jein. Nein insofern, als dass sie von der Sprache nicht unterstützt werden. Ja insofern, da man sie sich basteln kann:

    Wie? Beispiel:

    class base
    { 
        public:
           virtual ~base() {}
           ...
    };
    
    class derived1 : public base { ... };
    class derived2 : public base { ... };
    
    base* create(const string& what)
    {
        if(what == "derived1")
           return new derived1;
        else if(what == "derived2")
           return new derived2;
    
        else
           // Fehlerbehandlung.
    }
    
    int main()
    {
        base* derived1_obj = create("derived1");
        base* derived2_obj = create("derived2");
    
        ...
    
        delete derived1_obj;
        delete derived2_obj;
    }
    

    Mit dem obigen Beispiel wird ein "virtueller Ctor" simuliert. Je nach "String-Wert" von create(), wird entweder ein derived1 oder ein derived2 Objekt erzeugt.

    Einen "virtuellen Copy-Ctor" kannst du dir z.B. schreiben, indem du in der Basisklasse eine rein-virtuelle Memberfunktion clone() definierst, die in den abgeleiteten Klassen entsprechend redefiniert wird. Jetzt noch eine Funktion copy(const base* const rhs) schreiben, die abhängig davon, worauf rhs zeigt, ein derived1 oder ein derived2 klont... usw.

    Für weitere Informationen empfehle ich das Buch Mehr effektiv C++ programmieren von Scott Meyers. 🙂

    Gruß Caipi



  • Danke Caipi...

    Dass ich es mit einer clone-Methode simulieren kann,
    ist mir klar... 🙂



  • Dieser Thread wurde von Moderator/in c.rackwitz aus dem Forum ANSI C in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • VirtCon schrieb:

    Danke Caipi...

    Dass ich es mit einer clone-Methode simulieren kann,
    ist mir klar... 🙂

    Anders geht's auch nicht.



  • Hallo

    Caipi schrieb:

    chrische5 schrieb:

    Also wenn du nicht ableitest, brauchst du auch den Destruktor nicht virtuell machen.

    Auch wenn du von einer Basisklasse ableiten möchtest, muss der Dtor nicht zwangsläufig virtuell sein.

    Ich habe ja auch nicht geschriben, dass er virtuell sein muss, wenn man ableitet, sondern nur, dass es keinen Sinn macht den Destruktor virtuell zu machen, wenn man nicht ableitet. Optimiert der Compiler solche Sachen?

    chrische



  • Vermutlich nicht. Eine virtuelle Methode/Destruktor lässt den Compiler rtti erzeugen, dies macht er andernfalls nicht. Oft macht man nur deshalb einen virtuellen Destruktor, um rtti zu haben. Der Compiler müsste, um das wegzuoptimieren den ganzen Sourcecode nach dynamic_cast bezgl. deines Typs absuchen.


Anmelden zum Antworten