Вопрос

Форма.h

namespace Graphics {
    class Shape {
    public:
        virtual void Render(Point point) {};
    };
}

Прямая кишка.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;
};

Используется вот так:

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

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

Этот код заканчивается вызовом Shape::Render и не Rect::Render

Я предполагаю, что это происходит потому, что он разыгрывает Rect к a Shape, но я понятия не имею, как остановить это.Я пытаюсь позволить каждой фигуре управлять тем, как она визуализируется, переопределяя Render способ.

Есть какие-нибудь идеи о том, как этого добиться?

Это было полезно?

Решение

Вот ваша проблема:

struct ShapePointPair {
        Shape shape;
        Point location;
};

Вы храните Shape.Вы должны хранить Shape *, или shared_ptr<Shape> или что-то.Но не Shape;C++ — это не Java.

Когда вы назначаете Rect к Shape, только Shape часть копируется (это нарезка объекта).

Другие советы

Эта проблема называется нарезкой — при копировании в базу вы теряете производный функционал.Чтобы избежать этого, используйте указатели на базовый класс, т.е.

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

Проблема в том, что в вашем векторе вы храните копии объектов Shape, а копирование объекта Shape не копирует данные или функциональность его производных классов — вы нарезка полиморфизм прочь.

Управляйте объектами с помощью функций «Создать» и «Удалить», а также организуйте в векторе сохранение указателей на них.

Полиморфизм будет работать только с указателем на фигуру, а не с объектом фигуры.

Вы получаете доступ к объекту формы напрямую, чтобы переопределение работало. Вам необходимо получить доступ к объекту через указатель или ссылки.

Например, когда вы назначаете форму в ShapePointPair, код «разрезает» объект и копирует только бит формы в ShapePointPair.

Это будет означать, что вы должны наблюдать за управлением памятью - чтобы вы могли использовать умный указатель в форме struct shapepointpair {smart_pointer;Расположение точки;};

Нет, это не кастинг.

Вместо этого вы можете сохранить ссылку на базовый класс Point:

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

Эта ссылка должна быть установлена во время построения для struct ShapePointPair.Добавьте конструктор в ShapePointPair для этой цели.Должны быть переданы (вновь созданные) экземпляры Rect.

Также обратите внимание на ответственность за управление памятью (правильные написанные деструкторы и т.д.).

Вы можете попробовать boost::ptr_vector

http://www.boost.org/doc/libs/1_40_0/libs/ptr_container/doc/ptr_container.html

Я не уверен, что смогу хорошо объяснить, потому что у меня плохой английский.

Я думаю, вам придется использовать его ссылочный тип или тип указателя.потому что форма точно определяет, что она должна делать.

Если вы используете свой код напрямую, ваш ребенок попытается скопировать и выполнить работу с фигурами.Вот почему не работает ваша функция переопределения.

Используйте указатель или ссылку, как это.

указатель.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;
}

ссылка.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;
}

*пс:лично я использую абстрактную функцию (virtual void Something() = 0;).потому что я тоже иногда забывал об этом, поэтому воспринимаю это как синтаксическую ошибку.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top