Question

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;
};

Utilisé comme ceci:

std::vector<Graphics::ShapePointPair> theShapes = theSurface.getList();

for(int i = 0; i < theShapes.size(); i++) {
    theShapes[i].shape.Render(theShapes[i].location);
}

Ce code finit par appeler Shape::Render et non Rect::Render

Je suppose que c'est parce qu'il convertit le Rect en un Shape, mais je ne sais pas comment l'arrêter. J'essaie de laisser chaque forme contrôler son rendu en surchargeant la Render méthode.

Avez-vous des idées pour y parvenir?

Était-ce utile?

La solution

Voici votre problème:

struct ShapePointPair {
        Shape shape;
        Point location;
};

Vous stockez un Shape. Vous devriez stocker un Shape *, ou un shared_ptr<Shape> ou quelque chose comme ça. Mais pas un Rect; C ++ n'est pas Java.

Lorsque vous affectez un <=> à <=>, seule la partie <=> est en cours de copie (il s'agit de découpage en tranches ).

Autres conseils

Ce problème s'appelle le découpage en tranches. Vous perdez la fonctionnalité dérivée lors de la copie sur une base. Pour éviter cela, utilisez les pointeurs vers la classe de base, à savoir

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

Le problème est que, dans votre vecteur, vous stockez des copies d'objets Shape et que la copie d'un objet Shape ne copie pas les données ni les fonctionnalités de ses classes dérivées - vous êtes découper le polymorphisme.

Gérez les objets en utilisant new et delete, et faites en sorte que votre vecteur stocke les pointeurs qui les dirigent.

Le polymorphisme ne fonctionnera que d'un pointeur vers une forme, et non d'un objet de forme.

Vous accédez directement à l'objet de forme pour que le remplacement fonctionne, vous devez accéder à l'objet via un pointeur ou des références.

Par exemple, lorsque vous assignez la forme à l'objet ShapePointPair, le code "découpe" l'objet et ne copie que le bit Shape dans l'objet ShapePointPair

Cela signifie que vous devrez surveiller la gestion de la mémoire - vous pourrez donc utiliser un pointeur intelligent dans la structure.     ShapePointPair {            forme smart_pointer;             L'emplacement du point;     };

Non, ce n'est pas un casting.

Vous pouvez plutôt stocker une référence à la classe de base Point:

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

Cette référence doit être définie au moment de la construction pour struct ShapePointPair. Ajouter un constructeur à ShapePointPair pour cela objectif. Il doit être passé (nouvellement créé) des instances de Rect.

Observez également les responsabilités de la gestion de la mémoire destructeurs écrits, etc.).

Je ne suis pas sûr de bien expliquer parce que mon anglais est faible.

Je pense que vous devriez utiliser ce type de référence ou de pointeur. parce que la forme est exactement définie ce qu'elle doit faire.

Si vous utilisez votre code directement, votre enfant essaiera de copier et de faire fonctionner la forme. C'est pourquoi ne fonctionne pas votre fonction de remplacement.

utiliser un pointeur ou une référence comme ça.

pointeur.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: personnellement, j'utilise une fonction abstraite (void virtuel quelque chose () = 0;).  parce que je l'ai aussi oublié parfois, donc je l'attrape comme une erreur de syntaxe.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top