문제

모양 .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;
};

다음과 같이 사용 :

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 *,, a shared_ptr<Shape> 또는 뭔가. 그러나 아닙니다 Shape; C ++는 Java가 아닙니다.

할당 할 때 Rect ~로 Shape, 오직 Shape 부분이 복사되고 있습니다 (이것은입니다 물체 슬라이스).

다른 팁

이 문제를 슬라이싱이라고합니다.베이스에 복사 할 때 파생 된 기능을 잃습니다. 이 사용을 기본 클래스에 사용하지 않으려면 즉

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

문제는 벡터에서 모양 객체의 사본을 저장하고 있으며 모양 객체를 복사하면 파생 클래스의 데이터 또는 기능이 복사되지 않는다는 것입니다. 슬라이스 다형성.

새롭고 삭제를 사용하여 객체를 관리하고 벡터가 포인터를 저장하도록 배열하십시오.

다형성은 포인터에서 모양 대상이 아닌 모양으로 만 작동합니다.

포인터 또는 참조를 통해 객체에 액세스하는 데 필요한 재정의 작업을 위해 Shape Object에 직접 액세스하고 있습니다.

예를 들어 모양을 ShapePointPair에 할당하면 코드는 객체를 '슬라이스'하고 모양 비트를 ShapepointPair에만 복사합니다.

이렇게하면 메모리 관리를보아야한다는 의미입니다. 따라서 구조 ShapePointPair {Smart_Pointer Shape; 포인트 위치; };

아니요, 캐스팅이 아닙니다.

대신베이스 클래스 포인트에 대한 참조를 저장할 수 있습니다.

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

이 참조는 구조 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;
}

*PS : 개인적으로 나는 추상 함수를 사용합니다 (Virtual Void Something () = 0;). 때때로 잊어 버렸기 때문에 구문 오류로 포착합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top