Frage

Shape.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 landet Shape::Render Aufruf und nicht Rect::Render

Ich gehe davon aus das ist, weil es die Rect zu einem Shape wirft, aber ich habe keine Ahnung, wie es zu stoppen dies zu tun. Ich versuche, jede Form Kontrolle zu lassen, wie es durch das Überschreiben des Render Verfahrens gemacht wird.

Alle Ideen, wie dies zu erreichen?

War es hilfreich?

Lösung

Hier ist Ihr Problem:

struct ShapePointPair {
        Shape shape;
        Point location;
};

Sie sind Speichern eines Shape. Sie sollten eine Shape * oder ein shared_ptr<Shape> oder etwas werden zu speichern. Aber kein Shape; C ++ ist nicht Java.

Wenn Sie eine Rect zum Shape zuweisen, werden nur der Shape Teil kopiert wird (dies ist Objekt Slicing ).

Andere Tipps

Dieses Problem wird Slicing genannt - Sie die abgeleitete Funktionalität verlieren, wenn sie zu einer Basis zu kopieren. Um diese Verwendung Zeiger auf die Basisklasse zu vermeiden, das heißt

std::vector<Graphics::Shape*> s;
s.push_back(&some_rect);

Das Problem ist, dass in Ihrem Vektor Sie Kopien von Shape-Objekte speichern, und das Kopieren eines Shape-Objekt nicht die Daten oder Funktionalität seiner abgeleiteten Klassen nicht kopieren - du bist Slicing der Polymorphismus entfernt.

Verwalten

die Objekte neu verwenden und löschen, und ordnen Sie für Ihren Vektor zu speichern Zeiger auf sie.

Der Polymorphismus wird nur von einem Zeiger auf eine Form arbeiten, nicht aus einem Form-Objekt.

Sie den Zugriff auf das Shape-Objekt direkt für die Überschreibung arbeiten Sie das Objekt über einen Zeiger oder Verweise auf zugreifen müssen.

Zum Beispiel, wenn Sie assigne die Form in die ShapePointPair der Code ‚Scheibe‘ das Objekt und nur das Shape-Bit in die ShapePointPair kopieren

Auf diese Weise wird das heißen Speicherverwaltung zu sehen haben - so könnte man einen intelligenten Zeiger in der Struktur verwenden     ShapePointPair {            smart_pointer Form;             Punktposition;     };

Nein, es ist nicht gegossen wird.

Sie können stattdessen speichern einen Referenzpunkt zu Basisklasse:

struct ShapePointPair {
        Shape shape;
        Point &location;
};

Diese Referenz muss Bauzeit für struct eingestellt werden ShapePointPair. Fügen Sie einen Konstruktor ShapePointPair für diese Zweck. Es muss (neu erstellt) Instanzen übergeben werden Rect.

Beachten Sie auch die Speicherverwaltung responsiblities (proper geschrieben Destruktoren, usw.).

Ich bin nicht sicher, gut zu erklären, weil mein Englisch ist schlecht.

Ich denke, man sollte es Art Referenz oder Zeiger verwenden. Form, weil genau definiert ist, was es zu tun hat.

Wenn Sie Ihren Code direkt verwenden, versuchen Sie Ihr Kind zu kopieren und Arbeits der Form zu tun. Deshalb ist nicht Ihre Override-Funktion funktioniert.

Verwendung Zeiger oder eine Referenz wie diese.

pointer.h

class Parent {
public:
    virtual void work() { printf("parent is working now\n"); }
};
class Child1 {
public:
    virtual void work() { printf("child1 is working now\n"); }
};
class Child2 {
public:
    virtual void work() { printf("child2 is working now\n"); }
};
struct Holder {
    Parent* obj1;
    Parent* obj2;
};
int main() {
    Child1 child1;
    Child2 child2;
    Holder holder = { &child1, &child2 };
    holder.obj1->work();
    holder.obj2->work();
    return 0;
}

reference.h

class Parent {
public:
    virtual void work() { printf("parent is working now\n"); }
};
class Child1 {
public:
    virtual void work() { printf("child1 is working now\n"); }
};
class Child2 {
public:
    virtual void work() { printf("child2 is working now\n"); }
};
struct Holder {
    Parent& obj1;
    Parent& obj2;
};
int main() {
    Child1 child1;
    Child2 child2;
    Holder holder = { child1, child2 };
    holder.obj1.work();
    holder.obj2.work();
    return 0;
}

* ps: ich persönlich verwenden abstrakte Funktion (virtual void etwas () = 0;).  weil ich auch manchmal über sie vergessen haben, so dass ich es als Syntaxfehler fangen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top