Frage zu rein virtuellen Funktionen



  • Hallo, Leute!
    Kurze Frage zu rein virtuellen Funktionen. Ich will im Konstruktor einer abstrakten Klasse die Funktion aufrufen, die rein virtuell ist. Also so:

    [cpp]
    class PureVirtual
    {
    PureVirtual();
    ~PureVirtual();
    virtual void doSomething()=0;
    }
    PureVirtual::PureVirtual()
    {
    doSomething();
    }
    Der Linker meckert aber natürlich, dass er die Implementierung von doSomething nicht gefunden hat. (Also kommt eine rein virtuelle Geschichte gar nicht in Frage, obwohl sie logisch wäre...)
    Die Frage ist, ob, wenn ich PureVirtual::doSomething implementiere und dann es nochmal in einer abgeleiteten Klasse implementiere, wird dann im Konstruktor von PureVirtual (also der Basisklasse) die Methode der abgeleiteten Klasse aufgerufen? Wenn nein, versteht ihr mein Problem trotzdem und könnt mir weiterhelfen?
    Vielen Dank!!!
    Grüße
    Sören



  • die antwort ist: nein, es wird in keinem fall eine funktion aus der abgeleiteten klasse aufgerufen.

    die lösung lautet, im konstruktor der zumeist abgeleiteten klasse eine funktion der basisklasse aufzurufen (die nicht virtuell sein muss), die dann virtuelle funktionen aufruft.



  • soerenP schrieb:

    Ich will im Konstruktor einer abstrakten Klasse die Funktion aufrufen, die rein virtuell ist.

    Du solltest im Konstruktor keine virtuellen Funktionen aufrufen. Die Kind-Objekte sind noch nicht erstellt; was zu unerwarteten Problemen führen kann.

    Falls die Funktion virtuell ist, sollte die Funktion des Objekts aufgerufen werden. Das hat nichts mit virtuell oder rein virtuell zu tun.

    Edit: mir ist grad aufgefallen in C++ scheint das gar nicht zu gehen 🙂
    Glaube in C# ging das... hm.



  • camping wagon schrieb:

    die antwort ist: nein, es wird in keinem fall eine funktion aus der abgeleiteten klasse aufgerufen.

    die lösung lautet, im konstruktor der zumeist abgeleiteten klasse eine funktion der basisklasse aufzurufen (die nicht virtuell sein muss), die dann virtuelle funktionen aufruft.

    Oder Du machst eine virtuelle PostInitialize(..) Funktion, die z.B. mit einer Factory automatisch nach dem Konstruktor aufgerufen wird. (Ist eine Lösung, laut Herb Sutter.)



  • Du versuchst, eine Methode von einer abgeleiteten Klasse B zur Konstruktion seiner (rein virtuellen) Basisklasse A zu benutzen. Irgendwie riecht mir das nach einem grundlegenden Designfehler.
    Mal ganz davon abgesehen kann es nicht funktionieren, weil zur Konstruktion von A das B noch gar nicht zur Verfügung steht.



  • Tachyon schrieb:

    Du versuchst, eine Methode von einer abgeleiteten Klasse B zur Konstruktion seiner (rein virtuellen) Basisklasse A zu benutzen. Irgendwie riecht mir das nach einem grundlegenden Designfehler.
    Mal ganz davon abgesehen kann es nicht funktionieren, weil zur Konstruktion von A das B noch gar nicht zur Verfügung steht.

    Also, dass das auf diese Weise nicht funktionieren kann, da geb ich dir recht.
    Aber prinzipiell finde ich das Design gut. Ich wollte mit der rein virtuellen Funktion den "Ableiter" zwingen, diese wichtige, aber noch nicht implementierbare Funktion zu implementieren.
    Die Funktion, die implementiert werden muss, soll grundsätzlich im Konstruktor aufgerufen werden. Mit meiner Konstruktion wollte ich vermeiden, dass der "Ableiter" selbst die Funktion in seinem Konstruktor aufrufen muss. Da der Aufruf der Funktion quasi Pflicht sein soll, wollte ich es nicht dem User("Ableiter") überlassen.



  • Naja, aber wenn Du vom User Deines Interfaces erwartest (erzwingst), dass er eine Implementierung liefert, dann kannst Du doch auch erwarten, dass er den entsprechenden Aufruf durchführt.
    Hier wäre aber vielleicht auch eine Komposition sinnvoll. Irgendwie so vielleicht:

    #include <iostream>
    
    //Interface class
    class ObjectCtorInterface
    {
    public:
        virtual void veryImportantHelperMethod() = 0;
    };
    
    //Class using the interface
    class FlexibleCtoredClass
    {
    public:
        FlexibleCtoredClass
            ( ObjectCtorInterface& theInterface )
        {
            theInterface.veryImportantHelperMethod();
        }
    };
    
    //concrete class, satisfying the interface
    class mySpecialHelperClass : public ObjectCtorInterface
    {
    public:
        virtual void veryImportantHelperMethod()
        {
            std::cout << "My concrete implementation!\n";
        }
    };
    
    int main (int argc, char* argv[]) 
    {    
        mySpecialHelperClass helper;
    
        //uses interface classes
        FlexibleCtoredClass theClass(helper);
    
        return 0;
    }
    


  • Es kann nicht funktionieren, weil der konstruktor der Basisklasse vor dem Konstrukter der abgeleiteten klasse aufgerufen wird. Zu dem Zeitpunkt hat die klasse noch absolut keine information, zu was sie später abgeleitet werden wird. Wenn man hier rein virtuelle funktionen aufrufen könnte, wäre das absolut unlogisch,



  • Krux schrieb:

    Es kann nicht funktionieren, weil der konstruktor der Basisklasse vor dem Konstrukter der abgeleiteten klasse aufgerufen wird. Zu dem Zeitpunkt hat die klasse noch absolut keine information, zu was sie später abgeleitet werden wird. Wenn man hier rein virtuelle funktionen aufrufen könnte, wäre das absolut unlogisch,

    Wenn man es entsprechechend über eine Hilfsklasse+Interface macht, wie ich es oben beschrieben habe, wird das konkrete Objekt aber angelegt, BEVOR es in der benutzenden Klasse überhaupt zum Einsatz kommt.

    int main (int argc, char* argv[])
    {   
        //hier wird das Hilfsobjekt angelegt (so richtig und ganz konkret) 
        mySpecialHelperClass helper;
    
        //hier wird es benutzt
        FlexibleCtoredClass theClass(helper);
    
        return 0;
    }
    

Anmelden zum Antworten