2013-04-21 15 views
6

Dieser Code verweigert das Drucken der entsprechenden Meldungen an die Konsole, wenn ich sie ausführe. Die Verwendung von Zeigern anstelle von Referenzen scheint zu funktionieren (-> statt.). Ich bin neu bei OOP, also vergib mir, wenn du das lächerlich findest.Aufrufen virtueller Funktionen durch einen Verweis auf die Basisklasse

#include <iostream> 

using namespace std; 

class instrument { 
public: 
    virtual void play(){} 
}; 

class drum : public instrument { 
public: 
    void play(){ 
     cout << "dum, dum" << endl; 
    } 
}; 

class piano : public instrument { 
public: 
    void play(){ 
     cout << "pling" << endl; 
    } 
}; 

int main(){ 
    instrument i; 
    piano p; 
    drum d; 

    instrument &pi = i; 
    pi.play(); // - 

    pi = p; 
    pi.play(); // pling 

    pi = d; 
    pi.play(); // dum, dum 
} 
+9

Sie können einen Verweis auf das Objekt, auf das er verweist, nicht ändern, nachdem er bei der Initialisierung gebunden wurde. Gerade jetzt Ihre Feuerzuweisung Betreiber (und Auslösung [Objekt Slicing] (http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c/274634#274634) in den Prozess). – WhozCraig

+4

Machen Sie das eine Antwort, werden Sie, Herr? – jrok

+0

Ein Nebenproblem, aber Sie müssen einen virtuellen Destruktor in der Basisklasse erstellen. –

Antwort

15
instrument &pi = i; 

Sie hier pi machen beziehen sich auf die instrument Objekt i.

pi = p; 

Hier zuweisen Sie das Objekt pianop auf das Objekt, auf das pi. Die Referenz pi wird nicht auf das Objekt piano zurückgesetzt. Es bezieht sich immer noch auf das gleiche instrument Objekt wie zuvor. Es wurden nur unterschiedliche Inhalte mit dem implizit generierten Standard-Zuweisungsoperator zugewiesen. (In diesem Fall hat die Zuweisung keine Auswirkung, aber das Zuweisen eines abgeleiteten Typs zu einem Basistyp führt normalerweise zum Objekt-Slicing.) Wenn Sie pi.play() aufrufen, verweist die Referenz immer noch auf ein instrument Objekt und instrument::play wird ausgeführt.

Der Punkt ist, während Sie einen Zeiger auf ein anderes Objekt eines anderen Typs zeigen können, können Sie nicht dasselbe mit einer Referenz tun. Es zeigt immer auf das gleiche Objekt. Sie könnten Ihren Code reparieren, indem Sie mehrere Referenzen verwenden:

+1

Zeiger sind ein bisschen mehr vielseitig und flexibel als Referenzen, oder? – Venom

+0

@Venom-Nr. beide haben ihre Verwendung –

+1

@Venom Sie könnten flexibler sein, wenn Sie nur ihre rohe Funktionalität betrachten. Sie wollen diese Flexibilität jedoch nicht immer. In der Tat könnte es sogar zu Problemen führen. Wählen Sie den geeigneten Typ für den Job aus. –

Verwandte Themen