abgeleitete Klasseninstanzen über Basispointer-Array ansprechen?



  • Hi zusammen

    Ich hätte eine Frage zu Vererbung:

    Wenn ich eine Klasse "Base" habe und verschiedene abgeleitete Klassen, z.B. "Derived1", "Derived2" usw., kann ich dann über ein Array aus Pointern auf die Basisklasse auch die abgeleiteten Objekte ansprechen, also z.B. so:

    Base* pArray[4];
    
    Derived1 object1, object2;
    Derived2 object3, object4;
    
    pArray[0] = &object1;
    .
    .
    .
    


  • ja.



  • Sehr schön. Danke vielmals. 👍



  • sorry, falsch gelesen. du kannst (ohne cast) alles benutzen, was base zur verfügung stellt. du kannst aber keine derived-spezifika nutzen, wenn du nur einen base-pointer hast. dafür musst du den basepointer hochcasten (am besten mit dynamic_cast<>).



  • Aha d.h. also wenn ich in Base eine Methode foo() habe die als virtual
    deklariert ist und ich sie in Derived neu definiere wird bei einem Aufruf
    wie pArray[0]->foo() die Basis-Methode aufgerufen und nicht die abgeleitete oder?



  • Dave__R schrieb:

    Aha d.h. also wenn ich in Base eine Methode foo() habe die als virtual
    deklariert ist und ich sie in Derived neu definiere wird bei einem Aufruf
    wie pArray[0]->foo() die Basis-Methode aufgerufen und nicht die abgeleitete oder?

    Doch, wird sie. Das ist der Sinn von virtual.



  • Ah ok. Wenn ich das also richtig verstanden habe können Basispointer redefinierte virtual Methoden ansprechen, aber nicht z.B. Methoden die in der abgeleiteten Klasse ganz neu eingeführt wurden oder?

    Kann es sein dass man das mit den virtual Methoden unter "late binding" versteht?



  • Dave__R schrieb:

    Ah ok. Wenn ich das also richtig verstanden habe können Basispointer redefinierte virtual Methoden ansprechen, aber nicht z.B. Methoden die in der abgeleiteten Klasse ganz neu eingeführt wurden oder?

    Genau, Minibeispiel:

    class A
    {
      public:
        virtual ~A() {}
    
        void foo1() ( /*...*/ }
        virtual void foo2() ( /*...*/ }
    };
    
    class B : public A
    {
      public:
        void foo1() ( /*...*/ }
        void foo2() ( /*...*/ }
        void foo3() ( /*...*/ }
    };
    
    int main()
    {
      B b;
      A* a = &b;
    
      a->foo1(); // hier wird A::foo1 aufgerufen, da kein virtual
      a->foo2(); // hier wird B::foo2 aufgerufen (virtuelle Methode)
      // a->foo3(); - Nicht möglich, nicht in der Schnittstelle von A enthalten
    }
    

    Kann es sein dass man das mit den virtual Methoden unter "late binding" versteht?

    Da ich den Begriff in mehreren Zusammenhängen kenne (u.A. bei DLL-Schnittstellen) bin ich mit meiner Aussage etwas vorsichtig: Ja, so könnte man es nennen.

    cu André



  • Hervorragend. Genau so etwas brauche ich. Danke vielmals 👍 🙂



  • asc schrieb:

    class A
    {
      public:
        virtual ~A() {}
    
        void foo1() ( /*...*/ }
        virtual void foo2() ( /*...*/ }
    };
    
    class B : public A
    {
      public:
        void foo1() ( /*...*/ }
        void foo2() ( /*...*/ }
        void foo3() ( /*...*/ }
    };
    
    int main()
    {
      B b;
      A* a = &b;
    
      a->foo1(); // hier wird A::foo1 aufgerufen, da kein virtual
      a->foo2(); // hier wird B::foo2 aufgerufen (virtuelle Methode)
      // a->foo3(); - Nicht möglich, nicht in der Schnittstelle von A enthalten
    }
    

    In Zeile 25 würde aber ein dynamic_cast klappen:

    dynamic_cast<B*>(a)->foo3(); // ruft B::foo3 auf
    


  • cubeman schrieb:

    In Zeile 25 würde aber ein dynamic_cast klappen:

    dynamic_cast<B*>(a)->foo3(); // ruft B::foo3 auf
    

    Aber nur wenn die Konvertierung klappt... und ansonsten knallt es mit deiner Lösung (0-Zeiger) ! Das Ergebnis eines dynamic_cast gehört überprüft und nicht direkt verwendet.



  • Oder man verwendet dynamic-cast auf Referenzen oder boost's polymorphic_cast, die werfen eine Exception wenn die Konvertierung nicht klappt.

    Wenn man sich allerdings 100%ig sicher ist, kann man auch einen einfachen static_cast machen.


Log in to reply