2013-02-27 6 views
0

추상화에 대한 내 previous question에서 다음과 같은 또 다른 질문이 있습니다. 이벤트가 생성되면 이벤트 설정과 관련하여 또 다른 문제가 있습니다.추상베이스를 가진 객체에 알 수없는 타입을 전달합니다.

상황에 따라 모든 유형의 이벤트를 만들 수 있으며 데이터를 아무 문제없이 적용 할 수 있습니다 (전략 디자인 패턴 수정 버전 사용). 문제는 현재 이벤트가 생성 될 때 이벤트를 전달해야한다는 것입니다.

IEvent* newEvent = new SpeedEvent(eventID, interpolation, 50.0f); 

또는

IEvent* newEvent = new AnimationEvent(eventID, interpolation, &newAnimation); 

나는 데이터 객체의 생성에 무엇인지 알고있는 경우이 방법은 괜찮지 만, 나는 데이터가 인스턴스화 될 것입니다 무엇을 알 수 없습니다 많은 경우가있다 .

IEvent* newEvent = new SpeedEvent(eventID, interpolation); 

그리고 이런 식으로 그것을 데이터를 할당 :

eventManager->assignData(eventID, *unknown data type*); 

이 방법은, 내가 개체가 할 것

는 이상적 일 것이다 무엇

는 다음과 같은 새로운 이벤트를 생성하는 것입니다 데이터를 자체 방식으로 처리하십시오. 이 문제를 해결하는 방법에 대한 제안은 많이 드러나지 만, 가능한 경우 템플릿을 사용하지 않으려합니다.

내 현재 데이터 및 개체 구조는 이전 질문에 대한 답변에서 제안 된 것과 매우 유사합니다.

+0

오버 기능을 만들고 두 개의 매개 변수를 사용하고 관련'Event' 형 생성자'assignData (INT 이드베이스 * 데이터)'Base' –

+1

'유래의 모든 유형을 취할 수있는 자료의 수 ' 인스턴스화를 지연시켜 모든 데이터를 사용할 수 있도록하십시오. 누군가가 아직 그것을 사용할 수 없기 때문에 단순히 생성자 매개 변수를 이동하는 것은 좋은 계획이 아닙니다. 인스턴스화를 지연하고 모든 데이터를 사용할 수있을 때 개체를 만드는 것이 좋습니다. – tp1

+0

내 계획은 모든 새 이벤트에 기본값을 부여하는 것입니다 (예 : 이벤트의 속도는 보간되는 애니메이션의 기본값과 같습니다 (이 값은 존재합니다). 내가 할 수없는 일은 이벤트가 생성되면 사용자가 GUI를 사용하여 이벤트를 업데이트 할 수 있다는 것입니다. – Agenten

답변

0

데이터에 대한 제한이 없다면 좋은 이전 void *을 데이터 유형으로 사용하십시오. 콘크리트 핸들러 내부에는 핸들러 내부에 알려진 올바른 유형으로 캐스트됩니다.

데이터에 제한을 두려면 데이터 사양을 설명하고 가능한 구체적인 데이터 유형 각각에 대해 상속 한 interface/base를 정의하십시오. 파생 된 형식의 데이터를 제네릭 처리기 (기본 클래스에 대한 포인터를 허용하는)로 보냅니다. 핸들러 내부에서 데이터에 대해 정의한 공용 인터페이스를 사용하거나 단순히 구체적인 유형으로 캐스트 할 수 있습니다.

+0

나는 이런 종류의 시스템에 실제로 갔다. void 포인터를 사용하지 않고, 각 이벤트를 추상베이스에 대한 포인터로 저장하는 것을보고, 나는 필요한 모든 뮤 테이터에 접근하기 위해'dynamic_case <> '를 사용할 수있다. – Agenten

1

Boost.Any을 사용하면 알 수없는 데이터를 전송할 수 있습니다. 소스 사이트에서는 asignment를 사용하고 싱크 사이트에서는 any_cast를 사용하여 가치를 회복합니다. 편집

저 작은 코드 :

단순히 그것을 알 수없는 데이터 형식으로 부스트 :: 하나를 사용하고 (당신의 구체적인 유형) 당신의 가치를 asign. 구체적인 유형이 필요한 쪽에서는 any_cast를 사용합니다.

class EventManager { 
    //... 
public: 
    void asignData(std::size_t eventId, boost::any value); 
    boost::any getData(std::size_t eventId) const; 
}; 

eventManager->assignData(eventId, 12); // assignes an int 
eventManager->assignData(eventId, 12.0); // assignes an double 


int value1=boost::any_cast<int>(eventManager->getData(eventID)); // gets an int 
double value2=boost::any_cast<double>(eventManager->getData(eventID)); // gets a double 
+0

+1 부스트는 +1하지만 직접 코드 샘플은 유용 할 것입니다. – oDDsKooL

+0

가능한 경우 부스트 라이브러리를 사용하지 않으려합니다. 이미 인텔 스레드 빌딩 블록, DirectX 11, 신속한 XML 및 FBX SDK를 사용하고 있습니다. 내 두뇌가 다른 API/SDK를 처리 할 수 ​​있다고 생각하지 않습니다! – Agenten

+0

그것은 논쟁입니다. 하지만 Any를 포함한 Boost의 대부분은 헤더입니다. 포장을 풀고 포함 경로에 추가하기 만하면됩니다. 다른 방법으로는 http://www.boost.org/doc/libs/1_44_0/tools/bcp/doc/html/index.html을 사용하여 부스트를 빠르게 추출 할 수 있습니다 .Any. –

관련 문제