是否应该在QueryInterface实现中使用dynamic_cast?

时间:2011-02-03 09:34:38

标签: c++ com casting multiple-inheritance

实现IUnknown::QueryInterface()的典型方法如下:对每个支持的接口ID使用if-else-if链并执行以下操作:

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

现在static_cast is necessary在多继承方案中进行适当的指针调整。

我偶尔会看到使用dynamic_cast的实现。国际海事组织浪费时间 - 结果将是相同的,它只需要更长的时间,并使实施过度工程。

在将dynamic_cast指针复制到this void**实现的IUnknown::QueryInterface()参数之前,是否确实需要使用{{1}}指针?

2 个答案:

答案 0 :(得分:1)

QueryInterface的那些实现中,有必要使用“支持的接口ID”。例如。如果您决定在基类中实现QueryInterface,而不是为每个派生类重写它。

出现这种情况的情况是你有很多类似的类型,其中“类似”意味着“实现许多相同的接口”。即您有对象类型Derived1 ... DerivedN,它们都实现了Interface1 ... InterfaceM的某些子集。

这可能是游戏引擎的情况,其中游戏实体都实现了IMoveableIScriptableIFactoryIShootsIPlayerControlled的子集, IStealthyISensor,等等。当然,通过COM规则,当且仅当工厂还实现IFactory::QueryInterface时,您必须能够调用IMovable*并获得IMovable

您打算如何实施所有这些QueryInterface方法?最简单的方法是在GameObjectIUnknown之间插入IFactory基类,并使用GameObject::QueryInterface检查实现dynamic_cast。通过这种方式,您只需要一个实现,而不是每个具体类型的接口。

答案 1 :(得分:1)

QueryInterface()实际上是“动态强制转换”运算符的实现。将实现基于另一个需要另一个相同元数据变体(继承树)的实现,这没有任何意义。

一个好的编译器应该能够将其重新映射为static_cast