2013-01-04 5 views
2

저는 상속 개념에 익숙하지 않고 다음 문제에 대한 해결책을 찾기 위해 애 쓰고 있습니다.벡터와 공유 포인터가있는 파생 클래스는 어떻게 사용해야합니까?

나는 두 가지 수업 즉, 머리와 손이 있습니다. 나는이 클래스의 인스턴스를 주로 벡터의 요소로 사용한다. 두 클래스에는 공통된 메소드와 메소드 만 있습니다.

또한 개체의 공유 포인터를 처리합니다.

나는이

class BodyPart 
{ 
    public: 
    typedef boost::shared_ptr<BodyPart> pointer; 

    private: 
    int commonMember1; 
    double commonMember2; 

    public: 
    int commonMethod1(); 
    int CommonMethod2(); 
} 

처럼, 그것은 클래스 본문 부분을 만드는 것이었다 구현하는 가장 좋은 방법은 생각이

class Hand : public BodyPart 
{ 
    public: 
    typedef boost::shared_ptr<Hand> pointer; 

    private: 
    int numFingers; 

    public: 
    int getNumFingers(); 
    void printInfo(); 
} 

같은 두 개의 파생 클래스는 마지막으로 벡터를 선언하고 싶었다 BodyPart 요소 :

std::vector<BodyPart::pointer> cBodyParts; 

핸드 또는 헤드 요소가 포함되어 있고 hods 벡터 요소에 필요할 때.

그러나이 방법은 효과가없는 것 같습니다. 분명히 벡터 요소를 가져 오려고하면 컴파일러에서 BodyPart 공유 포인터를 Hand 공유 포인터로 변환 할 수 없다는 오류가 발생합니다. 게다가 벡터가 위와 같이 선언 된 경우 실제로 요소가 클래스에서 가져온 경우에도 해당 요소에서 getNumFinger()와 같은 파생 클래스에 특정한 메서드를 호출 할 수 없습니다.

이 문제를 해결할 적절한 방법이 있습니까? 아니면 내 접근 방식이 완전히 잘못 되었습니까? 미리 감사드립니다.

+0

반복되는'pointer' 하위 유형의 유용성이 무엇인지 모르겠습니다. 정규 상속을 사용하고'std :: vector >'을 사용합니다. 원하는 경우 공유 포인터를 typedef에 넣으십시오. – WhozCraig

답변

3

귀하의 접근 방식은 정확하지만 컴파일러도 마찬가지입니다. 기본 클래스에 대한 공유 포인터가있는 벡터를 사용하는 것이 좋지만 특정 기능을 사용하려면 실제 유형으로 변환해야합니다.

typedef boost::shared_ptr<Hand> pointer;은 쓸모가 없습니다. 기본 클래스에는 typedef 만 있으면됩니다. 스마트 포인터 간에는 캐스팅하지 않습니다. 기본 클래스 typedef의 이름을

으로 변경했습니다.

Alan의 설명에 좋은 점 : 기본 유형에 대한 포인터를 통해 파생 된 유형에 대한 포인터를 (간접적으로) 삭제할 것이므로 UB를 방지하려면 기본 클래스의 소멸자를 가상으로 만들어야합니다.

+0

+1 그리고 네, 스마트 포인터를 사용하는 사람이 처음부터 바뀌는 것을 보아 주어서 좋습니다. 그 이상이 있었으면 좋겠다. – WhozCraig

+1

파생 된 클래스가 아닌 기본 클래스에 대한 포인터를 저장하는 경우 기본 클래스의 소멸자를 가상으로 만들어야한다는 점이 중요합니다. – Alan

+0

@Alan 예, 좋은 지적입니다. –

2

귀하의 접근 방법은 (당신이 정말로 typedef 필요하지 않습니다하지만), 당신은 당신이 그것을 필요로 할 때 shared_ptr<Hand>shared_ptr<BodyPart>에서 변환 할 boost::static_pointer_cast (Doc here) 사용해야 할 권리입니다.

학습 중 어느 시점에서 enable_shared_from_this을보실 수도 있습니다.

관련 문제