2011-02-03 2 views
2

IUnknown::QueryInterface()을 구현하는 일반적인 방법은 다음과 같습니다 다중 상속 시나리오에서 적절한 포인터 조정 여기QueryInterface 구현에서 dynamic_cast를 사용해야하는 경우가 있습니까?

if(iid == __uuidof(IInterfaceN)) { 
    *ppv = static_cast<IInterfaceN>(this); 
    //call Addref(), return S_OK 
} 

이제 static_castis necessary 다음 각 지원되는 인터페이스 ID에 대한 if-else-if의 체인을 사용하지.

가끔씩 dynamic_cast을 사용하는 구현이 있습니다. 시간 낭비 인 IMO는 결과가 같을 것이고 시간이 오래 걸리고 구현이 과장되게 될 것입니다.

dynamic_cast를 사용하는 경우 IUnknown::QueryInterface() 구현 void** 매개 변수로 복사하기 전에 this 포인터를 캐스팅 실제로 필요가있다인가?

답변

1

QueryInterface의 구현에서 "지원되는 인터페이스 ID"를 알 필요가 없습니다. 예 : QueryInterface을 기본 클래스에 구현하고 모든 파생 클래스에 대해 재정의하지 않기로 결정한 경우

"비슷한"유형이 많은 상황에서 "비슷한"은 "많은 인터페이스를 동일하게 구현하는"것을 의미합니다. 나는. Derived1 ... ... InterfaceM의 일부 하위 집합을 모두 구현하는 DerivedN 개체 유형이 있습니다.

게임 엔티티 모두의 하위 집합을 구현하는 게임 엔진의 경우가 될 수 IMoveable, IScriptable, IFactory, IShoots, IPlayerControlled, IStealthy, ISensor, 등등. 물론 COM 규칙에 따라 IFactory::QueryInterface에 전화 할 수 있어야하며 IMovable을 공장에서 구현하는 경우에만 IMovable*을 가져올 수 있어야합니다.

어떻게 이러한 모든 QueryInterface 메서드를 구현할 예정입니까? IUnknownIFactory 사이에 GameObject 기본 클래스를 삽입하는 것이 가장 쉽고, dynamic_cast 수표를 사용하여 GameObject::QueryInterface을 구현하십시오. 이런 식으로, 구체적인 유형의 인터페이스 당 하나가 아닌 하나의 구현 만 필요합니다.

+0

Emm ... 이러한 계층 구조의 가장 간단한 예를 제공해 주시겠습니까? – sharptooth

+0

'Base'와'Derived1' ...'DerivedN' 클래스의 집합을 가정합니다. 여기서'Derived' 클래스는 각각'Interface1' ...'InterfaceM'의 임의 부분 집합을 구현합니다. 'Base :: QueryInterface'에서'this'가 요구 된 인터페이스에 대해'dynamic_cast'가 될 수 있는지를 확인합니다. – MSalters

+0

좋아, 나는 그것을 볼 수있다. 대답에 포함시켜 주시겠습니까? – sharptooth

1

QueryInterface()은 실제로 "동적 캐스트"연산자의 구현입니다. 같은 메타 데이터 (상속 트리)의 다른 변형을 필요로하는 다른 구현 위에 구현을 기반으로하는 것은 사실이 아닙니다.

좋은 컴파일러는 이것을 static_cast으로 다시 매핑 할 수 있어야합니다.

관련 문제