Abstrakte Methoden



  • Hi, zurzeit versuche ich eine abstracke Methode zu implementieren. So schaut das aus:

    class a {
      public:
        a() {
          do_stuff();
        }
      protected:
        virtual void do_stuff() = 0;
    };
    
    class b: public a {
      public:
        b() :
          a() {
        }
      protected:
        virtual void do_stuff() {
          // do useful stuff
        }
    };
    
    int main() {
      b obj;
    }
    

    Wenn ich das kompiliere erhalte ich diese Fehlermeldung:

    test.cpp: In constructor »a::a()«:
    test.cpp:4:16: Warnung: abstract virtual »virtual void a::do_stuff()« called from constructor
    

    Was mache ich falsch?



  • x4rd3n schrieb:

    Hi, zurzeit versuche ich eine abstracke Methode zu implementieren. So schaut das aus:

    class a {
      public:
        a() {
          do_stuff();
        }
      protected:
        virtual void do_stuff() = 0;
    };
    
    class b: public a {
      public:
        b() :
          a() {
        }
      protected:
        virtual void do_stuff() {
          // do useful stuff
        }
    };
    
    int main() {
      b obj;
    }
    

    Wenn ich das kompiliere erhalte ich diese Fehlermeldung:

    test.cpp: In constructor »a::a()«:
    test.cpp:4:16: Warnung: abstract virtual »virtual void a::do_stuff()« called from constructor
    

    Was mache ich falsch?

    Steht doch in der Fehlermeldung:

    class a {
      public:
        a() {
          do_stuff(); // <--- Warnung: abstract virtual »virtual void a::do_stuff()« called from constructor
        }
      protected:
        virtual void do_stuff() = 0;
    };
    


  • jo schon klar 🙂 Nur ist gewünscht das die methode b::do_stuff() dann ausgeführt wird wenn ein Objekt der Klasse b vorliegt.



  • Virtuelle Funktionen sollen nicht in im Konstruktor aufgerufen werde, weil die definitive Funktion noch nicht bekannt sein könnte, weil die Objekt noch nicht korrekt erzeugt wurden (und die vtable noch nicht besteht).

    Du wirst da wohl um eine Funktion, welche du danach aufrufst nicht herum kommen (oder ganz das Design anpassen).



  • Ok, klappt, danke!



  • Warum ruft der Konstruktor der abgeleiteten Klasse nicht eine qualifizierte Version von do_stuff() auf? Der Aufruf muss nicht virtuell erfolgen, wenn die genaue Klasse bekannt ist. Durch die Angabe der Klasse kann die Funktion statisch gebunden werden.

    b::b()
    : a()
    {
        b::do_stuff();
    }
    

    Die Alternative besteht darin, eine Factory-Funktion zur Initialisierung zu haben, die nach der eigentlichen Konstruktion noch zusätzliche Methoden aufruft.

    std::auto_ptr<a> create_b()
    {
        std::auto_ptr<a> result(new b);
        result->do_stuff();
    
        return result;
    }
    

    Je nachdem auch mit Wertsemantik statt auto_ptr , wenn das erwünscht ist.

    b create_b()
    {
        b result;
        result.do_stuff();
    
        return result;
    }
    

Anmelden zum Antworten