在COM中奇怪地使用空智能指针

在COM中奇怪地使用空智能指针,com,Com,如图所示,我不知道为什么m_SPSServer,一个接口指针,在测试为null时,可以用来调用成员函数CreateInstance()。谁能告诉我为什么 这是接口定义,我在接口中没有找到CreateInstance(),接口指针定义也没有。 仔细查看代码: m_spServer.CoCreateInstance(...); 有两点需要注意: m_spSever不是实际的指针。相反,它是类型为的智能指针模板类的实例。也就是说,它重载了->操作符以取消对底层原始指针的引用(IAtlasServ

如图所示,我不知道为什么m_SPSServer,一个接口指针,在测试为null时,可以用来调用成员函数CreateInstance()。谁能告诉我为什么

这是接口定义,我在接口中没有找到CreateInstance(),接口指针定义也没有。


仔细查看代码:

m_spServer.CoCreateInstance(...);
有两点需要注意:

  • m_spSever不是实际的指针。相反,它是类型为的智能指针模板类的实例。也就是说,它重载了
    ->
    操作符以取消对底层原始指针的引用(
    IAtlasServer*
    )。类似地,
    =
    操作符重载以测试空值

  • 该方法被调用为带有“点”的
    .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;
    
        ...
    };
    
    模板
    类CComPtrBase
    {
    ...
    布尔运算符==(_In_opt_T*pT)常量抛出()
    {
    返回p==pT;
    }
    ...
    _检查\u return\uhresult CoCreateInstance(
    _在uuCLSID rclsid中,
    _Inout_opt_LPUNKNOWN pUnkOuter=NULL,
    _在DWORD dwClsContext=CLSCTX_ALL)throw()中
    {
    ATLASSERT(p==NULL);
    return::CoCreateInstance(rclsid、pUnkOuter、dwClsContext、_u_uidof(T)、(void**)和p);
    }
    ...
    T*p;
    ...
    };
    
    您将看到CComPtr包装了一个名为“p”的本机(“原始”)指针成员变量。重载的
    ==运算符
    针对与之比较的本机指针类型测试p。名为CoCreateInstance的CComPtr上的方法只是断言它包含的原始指针已经为null,然后尝试使用原始指针作为“out”参数执行本机CoCreateInstance调用

    智能指针非常棒,非常适合COM编程。CComPtr的析构函数自动适当地调用底层原始指针上的“Release”。如果使用正确,您将避免常见的引用计数问题,而无需考虑“AddRef”和“Release”