2009-08-04 5 views
7

나는 이것에 무엇이 있는지 알 수 없다.C++ 오버라이드 방법

내가 엔티티의 벡터가 있고 현장에서 엔티티를 추가하고 얻을 수있는 장면 클래스가 다음과 같이

class Scene { 
    private: 
     // -- PRIVATE DATA ------ 
     vector<Entity> entityList; 
    public: 
     // -- STRUCTORS --------- 
     Scene(); 
     // -- PUBLIC METHODS ---- 
     void addEntity(Entity); // Add entity to list 
     Entity getEntity(int); // Get entity from list 
     int entityCount(); 
}; 

내 엔티티 클래스입니다 (출력 테스트입니다) :

당신으로

class Polygon: public Entity 
{ 
    private: 
     // -- PRIVATE DATA ------ 
     vector<Point2D> vertexList; // List of vertices 
    public: 
     // -- STRUCTORS --------- 
     Polygon() {}; // Default constructor 
     Polygon(vector<Point2D>); // Declare polygon by points 
     // -- PUBLIC METHODS ---- 
     int vertexCount(); // Return number of vertices 
     void addVertex(Point2D); // Add vertex 
     void draw() { cout << "Yes" << endl; }; // Draw polygon 
     // -- ACCESSORS --------- 
     Point2D getVertex(int); // Return vertex 
}; 

:

class Entity { 
    public: 
     virtual void draw() { cout << "No" << endl; }; 
}; 

그리고 나는 엔터티에서 상속 다각형 클래스가 그것은 Entity 클래스에서 상속받은 draw() 메서드를 재정의해야하는 draw() 메서드를 가지고 있습니다.

하지만 그렇지 않습니다. 다음 코드를 사용하는 경우 :

scene->getEntity(0).draw(); 

실체 공은 다각형 (또는 이상이어야 함) (그것이 다각형, 단지 법인이 아니다 것처럼), 그것은 "아니오"부모 방법에서 인쇄합니다. 사실, 나를 점점없이 다각형에 고유 한 모든 메소드를 호출 할 수 있도록하지 않는 것 :

'일부 메소드 이름이'무슨 일이야 '법인'

그래서 어떤 생각의 멤버가 아닌?

도움 주셔서 감사합니다.

UPDATE :

그래서 나는 첫 번째 대답에 주어진 코드를 구현했지만, 나는 목록에 내 다각형을 추가하는 방법을 모르겠어요. 이 같은?

const tr1::shared_ptr<Entity>& poly = new Polygon; 
poly->addVertex(Point2D(100,100)); 
poly->addVertex(Point2D(100,200)); 
poly->addVertex(Point2D(200,200)); 
poly->addVertex(Point2D(200,100)); 
scene->addEntity(poly); 

저는이 shared_ptr 비즈니스에 익숙하지 않았습니다.

+1

Scene 클래스의 Entity 객체 복사본보다는 Entities에 대한 포인터를 저장해보십시오. – chollida

답변

14

나는 당신이 당신의 호출 코드를 게시 할 필요가 있다고 생각하지만, 근본적으로 문제는 이것이다.

다른 구체적인 클래스에서 파생 된 구체적인 클래스 PolygonEntity입니다. addEntity 및 getEntity 함수는 Entity을 값으로 반환하므로 Entity을 전달하거나 가져 오려고하면 Entity 부분의 해당 객체 (분할 된 부분)와 객체의 파생 된 부분에 대한 정보 만 복사합니다 잃게 될 것이다.

또한 vectorEntity이며 기본 클래스 개체의 벡터이므로 기본 유형의 개체 이외의 다른 개체를 저장할 방법이 없습니다. 당신이 객체의 혼합 형식의 컬렉션이 필요하지만, 모든 Entity에서 파생 된 경우

, 당신은 같은 tr1::shared_ptr 또는 boost::shared_ptr 같이 동적으로 생성 된 객체와 스마트 포인터의 일종을 사용해야 할 수도 있습니다.

예.

class Scene { 
    private: 
     // -- PRIVATE DATA ------ 
     vector< std::tr1::shared_ptr<Entity> > entityList; 
    public: 
     // -- STRUCTORS --------- 
     Scene(); 
     // -- PUBLIC METHODS ---- 
     void addEntity(const std::tr1::shared_ptr<Entity>&); // Add entity to list 
     const std::tr1::shared_ptr<Entity> getEntity(int); // Get entity from list 
     int entityCount(); 
}; 

편집

공유 포인터에 로컬 CONST 참조를 사용하는 것은 조금 불분명하지만, 업데이트 된 호출 코드가 기본적으로 올바른 것입니다. 아마 뭔가 함께 갈 것

:

std::tr1::shared_ptr<Polygon> poly(new Polygon); 
poly->addVertex(Point2D(100,100)); 
poly->addVertex(Point2D(100,200)); 
poly->addVertex(Point2D(200,200)); 
poly->addVertex(Point2D(200,100)); 
scene->addEntity(poly); 
+3

또는 좀 더 그래픽 적으로 배치하려면 게시 된 코드가 다각형을 가져 와서 엔터티 크기의 상자에 넣고 모두 맞지는 않습니다. –

+0

OP를이 새 코드와 관련된 질문으로 업데이트했습니다. –

+0

이제 문제는 addVertex()가 Polygon에 고유하다는 것입니다. 오류 C2039 : 'addVertex': 'Entity'의 구성원이 아닙니다. 감사드립니다. (미안하지만, 나는이 여분의 질문을 코멘트에 게시해야하는지 확신 할 수 없다) –

1

chollida의 의견은 정확 : 당신은 유형의 엔티티에 대한 의미 메모리 위치에 입력 다각형의 개체를 추진, 그리고 을 소위로 실행중인 슬라이스. 추가 '다각형'정보가 분리되고 나머지는 모두 엔터티입니다.

이러한 상황에서 기본 클래스에 대한 포인터 (또는 가능한 경우 참조)를 저장해야합니다.

0

우선 포인터 (스마트 포인터 : 선호하는)를 먼저 Entity 인스턴스에 저장해야합니다. 삽입 할 때 Vector가 다시 할당되므로 getter 메서드를 호출하기 전에도 객체가 슬라이스됩니다.

getter 메소드의 반환 유형도 포인터 또는 참조 여야 해당 polimorphic 호출을 할 수 있습니다.

1

이렇게하려면 순수 가상 함수를 사용해야합니다.

class Entity 
{ 
public: 
    virtual void draw() = 0; 
}; 

그런 다음 개체에서 그리기 기능을 호출하고 개체에 대한 포인터도 사용해야합니다.

+0

>이 작업에는 순수 가상 함수를 사용해야합니다. 필수 사항은 아닙니다. Entity 클래스는 확실하게 구체적인 draw 메소드를 가질 수 있습니다. – chollida

0

다형성을 사용하려는 객체를 다루는 경우 일반적으로 값 의미 대신 참조 의미 (포인터 또는 참조를 통해 객체에 액세스)를 사용해야합니다.

이러한 방식으로 안전성을 보장하려면 전용 복사본 생성자와 할당 연산자를 만들어 모든 다형성 유형의 기본 클래스를 noncopyable으로 만드는 것이 좋습니다. 값 의미가 실수로 사용될 경우 코드가 단순히 불완전 해지기 때문에 슬라이싱을 효과적으로 방지 할 수 있습니다.