2013-06-18 3 views
0

내 게임/시뮬레이션 프레임 워크의 클래스 구조와 관련하여 진행 방법에 의문이 있습니다. 나는 주로 내 자신의 즐거움을 위해이 일을하고 있습니다, 이미 거기에 좋은 솔루션을 많이 :)이 알고C++ 다중 상속 디자인 문제

프레임 워크의 구조가 다른 것들 Actor들 포함, Scene의 사이. SceneActor은 모두 여러 가지 방식으로 작동 할 수 있습니다. WRT는 물건이 내부적으로 어떻게 작동 하는지를 나타냅니다. 그래서 같은 다중 상속을 사용하는 등의 행동을 구현 한 :

class ActorBase : public Object { ... }; 
class Actor : virtual public ActorBase { ... }; 
class CollisionBehavior : virtual public ActorBase { ... }; 
class BoundingBoxCollisionBehavior : public CollisionBehavior { ... }; 
class MyActor : public Actor, public BoundingBoxCollisionBehavior { ... }; 

이 방법은, 가상 상속을 사용하여, 나는 배우의 구현에서 무엇의 구현을 분리 할 수있는 배우가 무엇을 (또는 그것을 수행하는 방법). Actor...Behavior 클래스 모두 구현을 위해 공통 기본 클래스 ActorBase에 액세스해야하지만 일들은 깔끔하게 구분되어 있으므로 Behavior 클래스를 상속받은 클래스로 바꾸기 만하면 쉽게 객체의 동작을 변경할 수 있습니다.

이것은 각 동작이 자체 내부 규칙을 따르고 객체가 하나의 Behavior에서 상속받을 수 있기 때문에 (또는 모호한 함수 호출 등으로 인해 느슨한 부분이 깨지기 때문에) 서로 다른 두 개의 액터를 가질 수 없습니다. 행동은 서로 상호 작용합니다. 또한 V8 Javascript Engine을 프레임 워크에 통합 할 때 Actor (또는 Scene) 및 가능한 동작의 가능한 조합마다 래핑 된 하위 클래스를 만들어 JS에서 혼합 된 방식으로 이러한 개체를 인스턴스화해야합니다. 다시 말해, 다르게 동작하는 두 객체가 서로 상호 작용할 수 없기 때문에 충돌이 발생합니다 (적어도 모든 것에 해당하지는 않음).

나는이 같은 다중 상속 구조를 버려야한다고 생각하는 대안의 해결책 : Behavior을 필요로하는 각 객체는 각각 Behavior 그룹 (충돌 동작, 동작 동작 등)에 대해 하나씩 많은 배열을 가지고 있습니다. 각 가능한 동작에 대해 ...Behavior 개체를 사용하십시오. 객체에 기본 비헤이비어를 제공 할 수 있으며 필요할 때마다 (기본 비헤이비어가 다른 객체와 상호 작용이 발생 함) 하나의 객체에 이러한 비헤이비어를 추가하여 서로 상호 작용할 수 있습니다. 일종의 전환 정책이되어야하지만 문제는 아닙니다. 이는 순환 참조를 갖는 것을 의미합니다 (객체 인스턴스는 비헤이비어 인스턴스를 참조하고 비헤이비어 인스턴스는 비헤이비어 인스턴스에 포함 된 객체를 참조합니다). 비헤이비어는 고유 한 작업을 수행하는 데 필요한 기본 속성에 액세스 할 수 있습니다. Behavior 하위 클래스는 Actor 클래스의 friend s이어야하며 보호 된 멤버 및/또는 비공개 멤버에 액세스해야합니다. 나는이 길을 그다지 좋아하지 않는다. 나는이 문제를 해결하는보다 우아한 방법이있을 것이라고 생각한다. 아직 생각하지 못했다.

생각하십니까? :)

보너스 질문 : 행동이나 행동을 철자해야합니까? 네이티브 스피커가 아닙니다!

편집 : 보너스 질문을 해결했습니다 - 인터넷에 의존하고있는 위치에 따라 다릅니다. :)

편집 2 : 명확성을 위해 CollisionBehaviorBehavior에서 변경 (아래 답변을 참조)

+2

원어민이 아니지만 * 행동 *은 미국의 철자이지만 * 행동 *은 영국입니다 (또는 이미 들었습니다). 로마에있을 때, 로마인처럼 행동하십시오. – jrok

+1

배우들은 * 행동이 아닙니다 ** 상속 관계에 있습니다. 나는 내 행동을 구축하고 그들을 적절하게 내줄 것이다. – ChiefTwoPencils

+6

"Behavior"는 영어 철자입니다. "행동"은 미국에서 표준화 된 맞춤법 오류입니다. –

답변

1

난 당신이 여기 가지를 혼합하는 두렵다.당신은 행동의 많은 다른 종류 1가 언급 한 바와 같이 :

  • 도보 행동은 행동을 이야기
  • 싸움 동작은
  • ...

그리고 물론 그것은 아무한다 WalkingBehaviorFightingBehavior과 비교되므로 기본 클래스를 공유하도록하는 것이 바람직하지 않습니다. 이와 같이

, 당신이 바로 그의 행동을 검색하는 방법을 배우을 사용하고 제공해야한다고 생각 : 기본 동작이 좀 더 일반과 상호 작용할 수있는 방식으로 정의된다

class Actor { 
public: 
    virtual WalkingBehavior const& walkingBehavior() const { 
     return DefaultWalkingBehavior; 
    } 

    virtual FightingBehavior const& fightingBehavior() const { 
     return DefaultFightingBehavior; 
    } 

    // ... 
}; // class Actor 

그 클래스의 행동. 그런 다음 FightingBehavior과 같은 각 특정 인터페이스는이 동작을 이해하는 데 필요한 메소드를 제공해야합니다.

정보를 인코딩하는이 방법은 매우 다양하다는 점에 유의하십시오. 컴파일시 결정된 동작과 런타임에 결정된 동작 (런타임에 전개 될 수 있음)을 클라이언트에 혼합하지 않고 혼합 할 수 있습니다 .

개인적으로 나는 내 내장 브라우저 맞춤법 검사기를 따릅니다.

+0

이것은 실제로 우아합니다. 나는 그것을 숙고하고, 그것을 구현하고, 당신에게 돌아 가려고 노력할 것이다, 고마워! ;) – juandemarco

+0

또한, 나는 분명하지 않다는 것을 알고 있습니다. 각 행동 "그룹"에는 그 그룹의 다양한 행동이 상속받을 수있는 자체 기본 클래스가 있지만 동작에는 공통 기본 클래스가 없습니다. 그것은 그 질문에서 잘못 설명되었습니다. WalkingBehavior 기본 클래스에는 많은 걷기 동작 하위 클래스가 있습니다 (직선형, 행복하게 점프하는, 비웃음 등). 따라서 초기 구현 후에 Actor 서브 클래스는 필요한 경우 각 비헤이비어 그룹에서 상속해야합니다. – juandemarco

+0

감사합니다. 결국 저는 당신의 충고에 따라 설명했던 것과 비슷한 접근 방식을 취했습니다. 내가하려고했던 것보다 확실히 좋습니다! – juandemarco