2011-03-05 4 views
0

제목이 올바르게 지정되었지만 여기에 표시되는지 확실하지 않은 경우 :컴포지션 클래스의 캡슐화 C++

MapEntity를 포함하는 벡터가 포함 된지도 클래스가 있습니다. MapEntity는 Factory, Farm 및 다른 3 개의 클래스가 상속 된 클래스입니다.

이 5 개의 클래스는 모두 몇 초마다 "틱"되어야합니다.이 시점에서 그들은 모든 클래스에 대해 개별적인 기능을 수행하지만 맵 클래스 만이 해당 클래스를 "틱"할 수 있어야합니다.

C++에서이 유형의 캡슐화를 어떻게 지원합니까? 친구? 방금 공용 메서드를 사용하고 메서드를 오용하지 않아야합니까? (비록이 코드가 재배포되지 않아도 좋은 연습을하기 위해 적절한 캡슐화를 선호하지만)

다시 말하지만, 이것은 잘 표현되지 않았 음을 알고 있습니다. 미리 감사드립니다.

답변

2

구문 적으로 그 중 하나를 사용할 수 있습니다.

그러나 MapEntities에 외부에서 "체크"해야하는 경우 tick 메서드는 public 메서드의 일부 여야합니다. 실제로는 MapEntity 클래스의 가상 공개 메서드 여야합니다.

그리고 예, 공개 메소드는 적절한 캡슐화입니다. 그들은 당신이 할 수있는 일을 당신의 학급에 알린다. 이 경우 사용자는 Map 클래스이며 tick MapEntities가 될 수 있습니다.

당신은 경우에만 MapEntitiesMap 만 사용해야합니다 설계 입니다 (등 친구, 익명의 네임 스페이스) 다른 솔루션을 고려해야합니다.

+0

감사합니다 : D. 나는 가상 공개 메서드를 사용합니다 – Ell

2

friend을 사용할 수 있지만 MapEntity 클래스를 '틱'할 수있는 제한을 두지 않는 것이 좋습니다.

일반적으로 코드에 인공적 제한을 두는 것은 좋지 않은 방법입니다. 지도 클래스가이 함수를 지금 당장 호출 할 수 있기를 원한다고하더라도, 이것은 미래에 변경 될 수 있습니다.

+0

고맙습니다. 코드에 제한을 두는 것이 옳은 일이라고 생각했습니다. s – Ell

+0

아니요, 캡슐화를 사용하는 이유는 데이터를 보호하고 코드에 제한을 두지 않기 때문입니다. 대개 데이터를 보호하려는 경우 캡슐화를 사용하며 일반적으로 데이터 변경의 부작용을 적용합니다. –

0

friend을 사용하면지도 클래스에 MapEntities의 비공개가 표시되고 실제로는 tick 메서드가 아니라 캡슐화 정도가 낮아집니다.

0

내 의견으로는 귀하의 작업은 디자인 패턴 방문자 설명과 유사합니다.

class Visitor; 

class MapEntity 
{ 
    public: 
    virtual void tick(Visitor &v) = 0; 
}; 

class Factory: public MapEntity 
{ 
    public: 
    void accept(Visitor &v); 
    // ... 
}; 

class Farm: public MapEntity 
{ 
    public: 
    void tick(Visitor &v); 
    // ... 
}; 

class Mill: public MapEntity 
{ 
    public: 
    void tick(Visitor &v); 
    // ... 
}; 

class Visitor 
{ 
    public: 
    virtual void visit(Factory *e) = 0; 
    virtual void visit(Farm *e) = 0; 
    virtual void visit(Mill *e) = 0; 
}; 

void Factory::tick(Visitor &v) { v.visit(this); } 
void Farm::tick(Visitor &v) { v.visit(this); } 
void Mill::tick(Visitor &v) { v.visit(this); } 

class SomeVisitor: public Visitor 
{ 
    void visit(Factory *e) { /* ... */ }; 
    void visit(Farm *e) { /* ... */ }; 
    void visit(Mill *e) { /* ... */ }; 
}; 

class OtherVisitor: public Visitor { /* ... */ }; 

클라이언트 코드 : 정보 주셔서

MapEntity *enities[]; 
// ... 
SomeVisitor v1; 
OtherVisitor v2; 
for (int i = 0; i < N; ++i) 
{ 
    entities[i].tick(v1); 
} 
for (int i = 0; i < N; ++i) 
{ 
    entities[i].tick(v2); 
}