Zeiger auf Basisklasse -> Methode einer abgeleiteten Klasse aufrufen



  • 1. Du stehst zu deine letzten Aussage und speicherst deine Objekte in verschiedenen, passend getypten, Mengen.

    2. Du stehst zu deiner ersten Aussage und ergänzt das Bla-Protokoll entsprechend um eine foobar-Nachricht.

    Danke für die schnelle Antwort.

    Klar kann ich da jetzt wild Sachen ändern, bis es funktioniert, dafür gibts dann aber keine Punkte testiert. Mein Problem ist ja, dass ich die Schnittstelle(n) (hier z.B. den Zeiger auf die Basisklasse) vorgegeben kriege und damit die gewünschten Funktionen implementieren soll. Wenn das nicht so wäre, hätte ich erst garnich gefragt. Da es nach Deinen Angaben offensichtlich keine Alternative gibt, muss ich wohl wieder murksen. Tja, so kriegt man beigebracht guten Code in C++ zu schreiben...

    Gruß,

    Andre



  • class Base
    {
    protected:
    	std::string str;
    
    public:
    	Base(std::string str_): str(str_) {}
    	virtual ~Base() {}
    
    	void foo()
    	{
    		cout << "Base String: " << str << endl;
    	}
    };
    
    class Derived : public Base
    {
    public:
    	Derived(std::string str_): Base(str_) {}
    
    	void foo()
    	{
    		cout << "Derived String: " << str.c_str() << endl;
    	}
    };
    
    int main(void) 
    {
      Base *pBase = new Base("test");
      Derived *d = dynamic_cast<Derived*>(pBase);
      d->foo(); 
      delete pBase;
    
      cin.get();
    
      return 0;
    }
    

    warum wird beim aufruf von d->foo(); eine exception? der cast ging schief?? hm..

    cu



  • unique. schrieb:

    warum wird beim aufruf von d->foo(); eine exception? der cast ging schief?? hm..

    Vielleicht weil pBase auf kein Derived zeigt?
    [cpp]
    Base *pBase = new Derived("test");
    [/cpp]



  • warum muss das:

    Base *pBase = new Derived("test");
    

    sein?
    kann ich keinen upcast machen? dynamic_cast kann nur downcasts machen?
    cu



  • hm.. schrieb:

    warum muss das:

    Base *pBase = new Derived("test");
    

    sein?
    kann ich keinen upcast machen? dynamic_cast kann nur downcasts machen?

    Der dynamic_cast im Beispiel funktioniert auch nur weil pBase tatsächlich auf ein Derived zeigt. Du kannst keine Objekte casten, sondern nur Pointer oder Referenzen darauf.
    Mach dich einfach nochmal ein wenig über Vererbung schlau. Und vor allem achte darauf was HumeSikkins weiter oben schon geschrieben hat, dynamic_cast macht selten Sinn bzw. ist selten angebracht.



  • nagut!

    so funktionierts ja auch, dynamic_cast funktioniert also nur für downcasts? und static_cast kanns in beide richtungen...

    Base *pBase = new Base("test");
    Derived *d = static_cast<Derived*>(pBase);
    d->foo(); 
    delete pBase;
    

    cu



  • unique. schrieb:

    so funktionierts ja auch, dynamic_cast funktioniert also nur für downcasts?

    Nö. dynamic_cast kann selbstverständlich auch upcasts und crosscasts.

    unique. schrieb:

    Base *pBase = new Base("test");
    Derived *d = static_cast<Derived*>(pBase);
    d->foo(); 
    delete pBase;
    

    Der Code hat undefiniertes Verhalten. pBase dynamischer Typ ist Base, nicht Derived. Der Cast nach Derived ist damit illegal. Ein dynamic_cast würde dir dies durch einen Null-Pointer bzw. eine bad_cast-Exception (wenn du in eine Referenz castest) anzeigen.

    Btw: Bist du sicher, dass du überhaupt verstanden hast, was ein upcast/downcast ist?



  • Downcasting = wenn ein Basisklassenzeiger auf einen Zeiger einer abgeleiteten Klasse konvertiert werden soll.
    Upcasting = wenn ein Zeiger einer abgeleiteten Klasse auf einen Zeiger der Basisklasse konvertiert werden soll.

    mach ich das nicht?

    cu



  • unique. schrieb:

    Downcasting = wenn ein Basisklassenzeiger auf einen Zeiger einer abgeleiteten Klasse konvertiert werden soll.
    Upcasting = wenn ein Zeiger einer abgeleiteten Klasse auf einen Zeiger der Basisklasse konvertiert werden soll.
    mach ich das nicht?

    Du vergisst dabei eine Kleinigkeit. Ein legaler Downcast setzt voraus, dass der dynamische Typ des Objekts hinter dem Zeiger auch vom Typ der abgeleiteten Klasse (oder von einer weiter abgeleiteten Klasse) ist.

    Bei dir ist der dynamische Typ aber ein Base-Objekt und daran ändert sich durch den Cast überhaupt nichts.



  • Du vergisst dabei eine Kleinigkeit. Ein legaler Downcast setzt voraus, dass der dynamische Typ des Objekts hinter dem Zeiger auch vom Typ der abgeleiteten Klasse (oder von einer weiter abgeleiteten Klasse) ist.

    Bei dir ist der dynamische Typ aber ein Base-Objekt und daran ändert sich durch den Cast überhaupt nichts.

    Base *pBase = new Base("test");
    

    ...Pointer pBase vom typ Base zeigt auf ein Base objekt?

    wenn ich jetzt mache:

    pBase->foo();
    

    dann wird die methode der basisklasse aufgerufen...weil der Typ ja Base ist...

    Base *pBase = new Derived("test");
    

    ...der pBase Pointer vom typ Base zeigt auf ein Derived objekt?
    ...hier kann ich aber nur

    pBase->foo();
    

    aufrufen wenn ich eine public vererbung habe! ok?

    beides nennt man ja Basisklassenzeiger weil sie vom typ Base sind?

    mit dynamic_cast ändere ich nun meinen meinen Typ des Zeigers von Base auf die abgeleitete Klasse Derived...dazu muss zuvor der Basisklassenzeiger auf ein Derived Objekt zeigen, sonst gibt dynamic_cast einen NULL Pointer zurück..

    das würde dann:

    Derived *pBase = new Derived("test");
    

    entsprechen...?

    cu 😃


Anmelden zum Antworten