C++ Überschriebene Methode nicht immer genannt
Form.h
namespace Graphics {
class Shape {
public:
virtual void Render(Point point) {};
};
}
Rect.h
namespace Graphics {
class Rect : public Shape {
public:
Rect(float x, float y);
Rect();
void setSize(float x, float y);
virtual void Render(Point point);
private:
float sizeX;
float sizeY;
};
}
struct ShapePointPair {
Shape shape;
Point location;
};
Wie folgt verwendet:
std::vector<Graphics::ShapePointPair> theShapes = theSurface.getList();
for(int i = 0; i < theShapes.size(); i++) {
theShapes[i].shape.Render(theShapes[i].location);
}
Dieser code endet Aufruf Shape::Render
und nicht Rect::Render
Ich gehe davon aus dies ist weil es wirft die Rect
zu einem Shape
, aber ich habe keine Ahnung, wie um ihn zu stoppen, dies zu tun. Ich versuche, jede Form kontrollieren, wie es gemacht wird durch überschreiben der Render
Methode.
Irgendwelche Ideen auf, wie dies zu erreichen?
- Vielleicht möchten Sie, zeigen Sie uns den code, erstellt die vector-Elemente?
- Das problem und die Lösung sind nahezu identisch zu dieser stackoverflow.com/questions/1230006 Frage. Da gibt es, Sie haben einen Vektor von (struct containting a) konkrete Basisklasse, die Sie müssen erstellen, durch aufschneiden abgeleiteten Klassen, wenn Sie erwarten Rect::Render aufgerufen werden.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist dein problem:
Den Sie speichern eine
Shape
. Sollten Sie die Speicherung einerShape *
oder eineshared_ptr<Shape>
oder so etwas. Aber nicht einShape
; C++ ist nicht Java.Beim zuweisen der
Rect
zu denShape
nur dieShape
Teil kopiert wird (dies ist Objekt slicing).Dieses problem nennt sich slicing - Sie verlieren die abgeleitete Funktionalität beim kopieren auf einen sockel zu stellen.
Um dies zu vermeiden, verwenden Sie Zeiger auf die Basisklasse, d.h.
Das problem ist, dass in dem Vektor, den Sie speichern Kopien von Form Objekten, und kopieren ein Shape-Objekt kopiert nicht die Daten oder Funktionen von deren abgeleiteten Klassen - Sie sind schneiden der Polymorphismus entfernt.
Verwalten die Objekte mit new und delete, und vereinbaren Sie für Ihre Vektor zum speichern von Zeigern auf Sie.
Die Polymorphie funktioniert nur von einem Zeiger in eine Form, die nicht aus einem shape-Objekt.
Sie Zugriff auf das shape-Objekt, das direkt für das überschreiben zu arbeiten, benötigen Sie Zugriff auf das Objekt über einen Zeiger oder Referenzen.
Zum Beispiel, wenn Sie assigne die Form in der ShapePointPair wird der code 'Scheibe' das Objekt und kopiere nur die Form etwas in die ShapePointPair
Tun, dies bedeutet, Sie haben die Uhr Speicher-management - so könnten Sie ein smart-pointer in die struct
ShapePointPair {
smart_pointer Form;
Punkt-Lage;
};
Nein, es ist nicht Gießen.
Können Sie stattdessen speichern Sie einen Verweis auf baseclass Punkt:
Dieser Verweis muss gesetzt werden bei der Konstruktion Zeit für struct
ShapePointPair. Fügen Sie einen Konstruktor für diese ShapePointPair
Zweck. Es muss bestanden werden (neu erstellt) Instanzen von
Rect.
Beachten Sie auch die Speicher-management-Verantwortlichkeiten (richtige
geschrieben Destruktoren, etc.).
Könnten Sie versuchen, boost::ptr_vector
http://www.boost.org/doc/libs/1_40_0/libs/ptr_container/doc/ptr_container.html
Ich bin mir nicht sicher zu erklären, auch weil mein Englisch schlecht ist.
Ich denke, Sie sollten es verwenden, Verweis oder pointer-Typ.
denn Form ist genau definiert, was es zu tun hat.
Wenn Sie den code direkt, Ihr Kind versuchen, Sie zu kopieren und zu tun Form der Arbeit.
Das ist, warum funktioniert dein override-Funktion.
verwenden Sie Zeiger oder Referenz
wie diese.
Zeiger.h
Referenz.h
*ps: ich persönlich verwende abstrakte Funktion(virtual void irgendwas() = 0;).
weil ich auch vergaß es manchmal, damit ich es fangen kann wie syntax Fehler.