Pergunta

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

Usado como esta:

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

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

Este código acaba chamando Shape::Render e não Rect::Render

Estou assumindo que este é porque ele está lançando o Rect a um Shape, mas eu não tenho nenhuma idéia de como pará-lo fazendo isso. Eu estou tentando deixar que cada um controle da forma como ele é processado, substituindo o método Render.

Algumas ideias sobre como conseguir isso?

Foi útil?

Solução

Aqui está o problema:

struct ShapePointPair {
        Shape shape;
        Point location;
};

Você está armazenando um Shape. Você deve estar armazenando um Shape *, ou um shared_ptr<Shape> ou algo assim. Mas não um Shape; C ++ não é Java.

Quando você atribui um Rect ao Shape, apenas a parte Shape está sendo copiado (isto é objeto corte ).

Outras dicas

Este problema é chamado de corte - você perde a funcionalidade derivado ao copiar para a base. Para evitar isso ponteiros de uso para a classe base, ou seja,

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

O problema é que, em seu vetor você está armazenando cópias de objetos Shape, e copiar um objeto Shape não copia os dados ou funcionalidade de suas classes derivadas - você está corte o polimorfismo de distância.

Gerenciar os objetos usando novas e apagar e mandar para o seu vetor para armazenar ponteiros para eles.

O polimorfismo só irá funcionar a partir de um ponteiro para uma forma, não a partir de um objeto de forma.

Você está acessando o objeto de forma direta para a substituição para funcionar, você precisa acessar o objeto por meio de um ponteiro ou referências.

Por exemplo, quando você assigne a forma no ShapePointPair o código vai 'fatia' do objeto e só copiar o bit forma no ShapePointPair

Fazendo isso irá significar que você tem que prestar atenção gerenciamento de memória - assim você poderia usar um ponteiro inteligente na struct ShapePointPair { forma smart_pointer; Ponto de localização; };

Não, não está lançando.

Você pode, em vez armazenar uma referência a baseclass Point:

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

Esta referência deve ser definida em tempo de construção para struct ShapePointPair. Adicionar um construtor para ShapePointPair para este objetivo. Ele deve ser passado (recém-criada) casos de Rect.

Observe também as responsabilidades de gerenciamento de memória (própria destruidores escritas, etc.).

Eu não tenho certeza de explicar bem por causa do meu Inglês é pobre.

Eu acho que você deve ter para usá-lo referência ou tipo de ponteiro. porque forma é exatamente definido o que tem que fazer.

Se você usar seu código diretamente, a sua tentativa criança para copiar e fazer trabalho de forma. É por isso que não funciona sua função de override.

ponteiro de utilização ou de referência como esta.

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: Pessoalmente eu uso a função abstrato (virtual void algo () = 0;). porque eu também esqueci sobre ele algumas vezes para que eu pegá-lo como erro de sintaxe.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top