Virtualität und Referenzen



  • Hey Leute,

    wenn man folgenden Zusammenhang hat:

    class A {
    
    public:
    	virtual void foo() { cout << "A" << endl; }
    
    };
    
    class B : public A {
    
    public:
    	void foo() { cout << "B" << endl; }
    
    };
    
    void bar(A &a) { 
    	a.foo();	
    }
    
    int main()
    {
    	B b;
    	bar(b);
    
    	return 0;
    }
    

    dann erhält man wie erwartet die Ausgabe "B".

    Ändere ich jetzt den Code aber folgendermaßen ab:

    /* ... */
    
    void g(A a) { 
    	a.foo();	
    }
    
    /* ... */
    

    d.h. übergibt man den Parameter an "bar" nicht mehr per Referenz erhält man trotz "virtual" die Ausgabe "A".

    Was genau passiert hier, beim Aufruf von "g(b)" in der main-Funktion?
    Wird der Parameter hier so kopiert (Stichwort: Call-By-Value), dass die Kopie danach eine Instanz der Klasse A ist?

    Falls ja ist dies schon eine Stolperfalle oder ist das Verhalten so gewünscht und tiefsinniger?

    Gruß 🙂



  • Stichworte: dynamic binding, static binding.
    Der Compieler sieht halt an der Stelle den statischen Typ "A" - keine Referenz oder Zeiger. Deshalb geht er davon aus, dass an der Stelle auch wirklich nur ein "A" ist, und baut einen direkten Aufruf von A::foo() ein - der Programmierer will es ja so.



  • In dem Moment in dem du kopierst, hast du auch wirklich ein A. Geht ja auch gar nicht anders - sonst müsste A ja immer unterschiedlich groß sein. 😉



  • Im Wesentlichen ist a eine lokale Kopie des A-Subobjekts von b.
    Google mal nach "slicing" in Verbindung mit "c++".

    Bei so vielen Anfängerfragen dürfte Dir doch inzwischen die Wichtigkeit gescheiter C++ Literatur aufgefallen sein! Oder soll das Spiel hier noch ein halbes Jahr weitergehen?



  • Die Literatur schweift leider teilweise sehr extrem aus, deswegen habe ich des öfteren hier Frage gestellt, meist aber mit dem Ziel handfeste Begriffe zu bekommen wie Object-Slicing um gezielt suchen zu können.

    Ich hoffe die ganzen Fragen stören nicht zu sehr, falls doch lasst es mich wissen.

    Viele Grüße 🙂


Anmelden zum Antworten