IUnknown 指针引用

Posted

技术标签:

【中文标题】IUnknown 指针引用【英文标题】:IUnknown pointer reference 【发布时间】:2013-11-02 07:25:09 【问题描述】:

为什么 Visual Studio 编译器很满意

void fn(int *&i) 

    ;

void fn(IUnknown *const &p)

    ;

但不是

void fn(IUnkown *&p)

    ;

称呼它的样子

IDXGIFactory *df = nullptr;
// init df
fn(df);

编译错误是

3 IntelliSense:无法使用“IDXGIFactory *”类型的值初始化“IUnknown *&”类型的引用(非 const 限定)c:\Users\Carl\Documents\Visual Studio 2013\Projects\Project1\项目5\main.cpp 29 10 项目5

我在研究中发现的最接近的事情是编译器一次只会进行一次类型转换,但这不可能是正确的,因为 const & 版本应该会中断类型和常量转换;但是实际上无法编译的是 & 版本。

【问题讨论】:

【参考方案1】:

非常量左值引用(如IUnknown*&)只能绑定到一个左值;它不能绑定到 rvalue。一个 const 限定的左值引用(如 IUnknown* const&可以绑定到一个 右值

考虑一个不涉及指针或函数调用的更简单的情况会更容易:

int i = 0;

double        x = i; // (1) Well-formed
double const& y = i; // (2) Well-formed
double&       z = i; // (3) Ill-formed

这里,iint 类型的对象。在表达式中使用i 时,它是一个左值

(1)中,我们从iint类型)初始化对象xdouble类型)。类型不匹配,但这没关系,因为存在从intdouble 的隐式转换。这个转换的“结果”是一个double类型的rvalue表达式(*),用于初始化x

(2) 中,我们从i 初始化常量限定引用ydouble const& 类型)。同样,类型不匹配,因此使用隐式转换将int 转换为double。这种转换的“结果”是一个右值。如开头所述,const 限定引用可以绑定到 rvalue,因此y 绑定到转换的“结果”。

(3)中,我们尝试从i 初始化非常量引用zdouble& 类型)。类型不匹配,因此需要进行转换。此处不能使用转换,因为转换的“结果”是一个右值,并且如开头所述,非常量引用不能绑定到一个右值 .

C++ 有特殊规则允许 const 左值引用绑定到 rvalue 表达式。您可以从 *** 上的其他问题中找出原因,例如 "How come a non-const reference cannot bind to a temporary object?"

您的情况与此情况完全相同:参数的类型(IDXGIFactory*)与参数的类型(IUnknown* 或对其的引用)不同,因此需要隐式转换将实参转换为参数类型(在这种情况下,它是从指向派生类的指针指向基类的指针的转换)。然而,这种转换的“结果”是一个右值表达式,因此它不能绑定到非常量引用IUnknown*&


(*)真的是prvalue;为简单起见,我在此答案中使用了 C++98 表达式分类法。有关 C++11 值类别的信息,请参阅 this question。

【讨论】:

the "result" of the conversion is an rvalue 是我所缺少的。谢谢!

以上是关于IUnknown 指针引用的主要内容,如果未能解决你的问题,请参考以下文章

为啥通过同一个 COM 对象的不同接口检索到的 IUnknown* 指针具有相同的值?

继承接口 & IUnknown , IDispatch 方法定义

com关于IUnknown接口

为啥我的 IUnknown 释放函数会阻塞我的子线程?

分布式系统架构-samgr/source系统服务开发框架基础代码iunknown.c讲解

对于进程间 COM 对象,在不使用 QueryInterface 的情况下将 IDispatch* 转换为 IUnknown* 是不是安全?