2017-07-06 32 views
1

如图所示,我不知道为什么当测试为null时,接口指针m_spServer可以用来调用成员函数CreateInstance()。有谁能告诉我为什么?在COM中奇怪的使用空的智能指针

enter image description here

这是接口定义,余did't在接口发现的CreateInstance(),无论是接口指针定义。密切关注代码

enter image description here

回答

1

看:

m_spServer.CoCreateInstance(...); 

有两点需要注意:

  1. m_spSever 不是一个实际的指针。相反,它是智能指针模板类型CComPtr的一个实例。也就是说,它已经超载了->运算符来解引用底层的原始指针(IAtlasServer*)。类似地,==运算符被重载以测试无效性。

  2. 该方法被调用为带有“点”的.CoCreateInstance。不是带有“箭头”的->CoCreateInstance。智能指针从不“空”。它包含的指针可能非常好。这意味着该方法在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”的本地(“原始”)指针成员变量。重载的== operator针对与之比较的本机指针类型进行测试。 CComPtr上名为CoCreateInstance的方法简单地声明它包含的原始指针已经为空,然后尝试使用原始指针作为“out”参数进行本地CoCreateInstance调用。

智能指针很棒,对于COM编程非常棒。 CComPtr的析构函数会自动在基础原始指针上自动调用“Release”。如果使用得当,您将避免常见的引用计数问题,而无需考虑“AddRef”和“Release”。

+0

好的。我懂了。很酷。 – wason