2013-10-30 3 views
3

함께 객체C++ 저장 기지와 파생 클래스는 내가 두 클래스 되세요

class Door: public Thing { 

private: 
    bool open; 

public: 

    int targetLocation; 

    Door(int _code, string _name, string _desc, int _loc, int _targetLoc) : 
      Thing(_code, _name, _desc, _loc, false) { 
     open = false; 
     targetLocation = _targetLoc; 
    } 
    void Use() { 
     open = true; 
    } 
    void Close() { 
     open = false; 
    } 
    bool isOpen() { 
     return open; 
    } 
}; 

는 공개/부가 요소를 잊어을 ...

기본 클래스의 일부 객체와 파생 클래스의 객체 일부를 저장해야합니다. 이 :

vector < Thing*> allThings; 
things.push_back(new Thing(THING1, "THING1", "some thing", LOC1, true)); 
things.push_back(new Door(DOOR1, "DOOR1", "some door", LOC1, LOC2)); 

그러나이 경우

이 .. 때문에 슬라이스의 연결할 수 없습니다 사용(),() 열기를 ISOPEN() 함수를

당신이 몇 가지 제안이 있습니까이 어떻게 저장하기 vector<Thing*>vector<Door*>의 새 구조를 만들지 않고 개체를 함께 ??

감사

대신 인스턴스의
+1

당신이'것 *'s의를 저장하는 경우,이 슬라이스되지 않습니다 : 그것은 아무 의미가 없기 때문에 ThingisOpen()을 가지고 당신이 할 수없는 경우, 같은 Visitor Pattern 같은 고급 솔루션을 사용하는 것이 (당신은 근심의 계급 데이터를 파괴하지 않는다, 당신은 지금 막 거기에 있다는 것을 모르고있다). 'Door' 객체는 손상되지 않습니다. 파생 된 클래스 함수를 사용하려면 나중에 다시 가져 오는 방법이 필요합니다. – BoBTFish

답변

5

당신이 다형성 (polymorphic)와 객체의 용기를 필요로 문제에 대한 좋은 해결책은 고유 포인터의 벡터이다 :

std::vector<std::unique_ptr<Thing>> 

이 상황에서 어떤 슬라이스가 없을 것입니다,하지만 당신은 파악해야 할 것 Use(), Open()isOpen()으로 전화해도됩니다.

파생 된 클래스에서 기본으로 메서드를 이동할 수 있으면 이동하십시오.

class Thing; 
class Door; 
struct Visitor { 
    virtual void visitThing(Thing &t) = 0; 
    virtual void visitDoor(Door &d) = 0; 
}; 
class Thing { 
    ... 
    virtual void accept(Visitor &v) { 
     v.visitThing(*this); 
    } 
}; 
class Door : public Thing { 
    ... 
    virtual void accept(Visitor &v) { 
     v.visitDoor(*this); 
    } 
} 
+0

Visitor Pattern 솔루션의 경우 - Door 또는 Class 클래스가 Visitor에서 상속되지 않는 것처럼 멤버 func이 순수 가상이어야합니다. 또한 귀하의 링크는 Visitor 패턴보다는 Iterator Pattern에 대한 위키피디아 기사를 가리키는 것으로 보입니다. – goldenmean

+0

@ goldenmean 기능은 순수 가상 일 필요는 없지만 대개는 있습니다. 이 수업은 방문객이 아닌 * 방문 가능 *이기 때문에'문 '이나'사물 '도'방문자'를 상속 받아야합니다. 그들은'Visitor'가 스스로 방문 할 수있게합니다 (그러므로'Accept' 함수). 프로그램은'std :: vector >'을 만들고,'Visitor'를 상속받은 클래스를 만들고, 그 객체를 차례대로 벡터의 모든 요소에 전달합니다. 요소는 방문객에게 어떤 유형인지 알려주며 다시 전화를 겁니다. 자세한 설명은 답변의 링크를 참조하십시오.이 패턴은 이해할만한 가치가 있습니다. – dasblinkenlight

1

포인터를 저장하고, 기본 클래스 (들)에서 가상 공공 및 보호 방법을 선언합니다.