在 COM 中奇怪地使用空智能指针
Strange use of null smart pointer in COM
如图所示,不知道为什么m_spServer,一个接口指针,当测试为null时,可以用来调用一个成员函数CreateInstance()。谁能告诉我为什么?
这是接口定义,我在接口中没有找到CreateInstance(),也没有找到接口指针定义。
仔细看代码:
m_spServer.CoCreateInstance(...);
需要注意两点:
m_spSever 不是一个真正的指针。相反,它是类型 CComPtr 的 智能指针 模板 class 的一个实例。也就是说,它重载了 ->
运算符以取消引用底层原始指针 (IAtlasServer*
)。同样,==
运算符被重载以测试是否为空。
方法被调用为 .CoCreateInstance
和 "dot"。不是 ->CoCreateInstance
和 "arrow"。智能指针永远不会是"null"。它包含的指针可能是。这意味着该方法是在 CComPtr 实例本身上调用的,而不是在底层原始指针上。
让我们看看 CComPtr::CoCreateInstance 的实现。
template <class T>
class CComPtrBase
{
...
bool operator==(_In_opt_ T* pT) const throw()
{
return p == pT;
}
...
_Check_return_ HRESULT CoCreateInstance(
_In_ REFCLSID rclsid,
_Inout_opt_ LPUNKNOWN pUnkOuter = NULL,
_In_ DWORD dwClsContext = CLSCTX_ALL) throw()
{
ATLASSERT(p == NULL);
return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
}
...
T* p;
...
};
您会看到 CComPtr 包装了一个名为 "p" 的本机 ("raw") 指针成员变量。重载 == operator
测试 p 与正在比较的本机指针类型。 CComPtr 上名为 CoCreateInstance 的方法简单地断言它包含的原始指针已经为空,然后尝试使用原始指针作为 "out" 参数执行本机 CoCreateInstance 调用。
智能指针很棒,非常适合 COM 编程。 CComPtr 的析构函数会自动适当地在底层原始指针上调用 "Release"。如果使用得当,您将避免常见的引用计数问题,而无需考虑 "AddRef" 和 "Release".
如图所示,不知道为什么m_spServer,一个接口指针,当测试为null时,可以用来调用一个成员函数CreateInstance()。谁能告诉我为什么?
这是接口定义,我在接口中没有找到CreateInstance(),也没有找到接口指针定义。
仔细看代码:
m_spServer.CoCreateInstance(...);
需要注意两点:
m_spSever 不是一个真正的指针。相反,它是类型 CComPtr 的 智能指针 模板 class 的一个实例。也就是说,它重载了
->
运算符以取消引用底层原始指针 (IAtlasServer*
)。同样,==
运算符被重载以测试是否为空。方法被调用为
.CoCreateInstance
和 "dot"。不是->CoCreateInstance
和 "arrow"。智能指针永远不会是"null"。它包含的指针可能是。这意味着该方法是在 CComPtr 实例本身上调用的,而不是在底层原始指针上。
让我们看看 CComPtr::CoCreateInstance 的实现。
template <class T>
class CComPtrBase
{
...
bool operator==(_In_opt_ T* pT) const throw()
{
return p == pT;
}
...
_Check_return_ HRESULT CoCreateInstance(
_In_ REFCLSID rclsid,
_Inout_opt_ LPUNKNOWN pUnkOuter = NULL,
_In_ DWORD dwClsContext = CLSCTX_ALL) throw()
{
ATLASSERT(p == NULL);
return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
}
...
T* p;
...
};
您会看到 CComPtr 包装了一个名为 "p" 的本机 ("raw") 指针成员变量。重载 == operator
测试 p 与正在比较的本机指针类型。 CComPtr 上名为 CoCreateInstance 的方法简单地断言它包含的原始指针已经为空,然后尝试使用原始指针作为 "out" 参数执行本机 CoCreateInstance 调用。
智能指针很棒,非常适合 COM 编程。 CComPtr 的析构函数会自动适当地在底层原始指针上调用 "Release"。如果使用得当,您将避免常见的引用计数问题,而无需考虑 "AddRef" 和 "Release".