【发布时间】:2026-01-15 16:50:02
【问题描述】:
假设我有一个实现两个或多个 COM 接口的类:
class CMyClass : public IInterface1, public IInterface2 {
};
我看到的几乎所有文档都表明,当我为 IUnknown 实现 QueryInterface() 时,我明确地将 this 指针向上转换为其中一个接口:
if( iid == __uuidof( IUnknown ) ) {
*ppv = static_cast<IInterface1>( this );
//call Addref(), return S_OK
}
问题是为什么我不能直接复制这个?
if( iid == __uuidof( IUnknown ) ) {
*ppv = this;
//call Addref(), return S_OK
}
文档通常说,如果我这样做,我将违反对同一对象的任何 QueryInterface() 调用必须返回完全相同的值的要求。
我不太明白。他们的意思是,如果我对 IInterface2 进行 QI() 并通过该指针调用 QueryInterface(),C++ 将传递 this 与如果我对 IInterface2 进行 QI() 略有不同,因为 C++ 每次都会使 this 指向一个子对象?
【问题讨论】:
-
void** 在 QueryInterface() 示例中像往常一样。
-
也是如此:C* c = static_cast(this);保证指向正确子类的指针?还是我必须使用 dynamic_cast?
-
static_cast 如果您转换为基类就足够了 - 编译器有足够的数据在编译期间进行所有必要的调整。编译器将拒绝对派生类执行 static_cast,但 dynamic_cast 仍然可以成功。
-
根据你的建议
*ppv = this将指向基地?我在标准中找不到任何可以证实这一点的东西。可以吗? -
*ppv = static_cast<IInterface1>( this );甚至这个语句也会导致未定义的行为,因为当类具有非标准布局时,标准不保证指针不可转换(即您将指针返回到IInterface1,而不是 @987654327 @,只是假设它会是相同的)。而CMyClass是一个非标准的布局类,原因有很多。在 10 年过去之后,我很高兴您能分享您目前对此事的了解。
标签: c++ visual-c++ com multiple-inheritance