测试CC中的CComPtr是否为空

时间:2015-06-17 20:46:46

标签: c++ visual-studio-2013 com

我对COM智能指针类CComPtr的使用有疑问。我正在关注documentation中的一个示例,似乎代码不会在CoCreateInstance()上调用CComPtr(它只是在赋值之前声明它)。

所以我写了一个这样的测试程序:

#include "stdafx.h"
#include "atlbase.h"
#include <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
    CComPtr<int> myint = nullptr;
    if (myint == nullptr) {
        std::cout << "yes" << std::endl;
    }
    return 0;
}

它在visual-studio 2013中出现以下错误:

------ Build started: Project: ConsoleApplication2, Configuration: Debug Win32 ------

  ConsoleApplication2.cpp

c:\program files (x86)\microsoft visual studio 12.0\vc\atlmfc\include\atlcomcli.h(177): error C2227: left of '->Release' must point to class/struct/union/generic type

          type is 'int *'

          c:\program files (x86)\microsoft visual studio 12.0\vc\atlmfc\include\atlcomcli.h(175) : while compiling class template member function 'ATL::CComPtrBase::~CComPtrBase(void) throw()'

          with

          [

              T=int

          ]

          c:\users\calvi_000\documents\visual studio 2013\projects\consoleapplication2\consoleapplication2\consoleapplication2.cpp(18) : see reference to function template instantiation 'ATL::CComPtrBase::~CComPtrBase(void) throw()' being compiled

          with

          [

              T=int

          ]

          c:\program files (x86)\microsoft visual studio 12.0\vc\atlmfc\include\atlcomcli.h(317) : see reference to class template instantiation 'ATL::CComPtrBase' being compiled

          with

          [

              T=int

          ]

          c:\users\calvi_000\documents\visual studio 2013\projects\consoleapplication2\consoleapplication2\consoleapplication2.cpp(10) : see reference to class template instantiation 'ATL::CComPtr' being compiled

========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

为什么将nullptr分配给CComPtr对象是违法的?是否有任何方法可以用来检查CComPtr是否拥有任何对象?像if (myint == nullptr)这样的调用是否足以检查这个智能指针是否没有任何对象?

1 个答案:

答案 0 :(得分:6)

  

为什么将nullptr分配给CComPtr对象是非法的?

不是。正如Hans所指出的,CComPtr只能与COM接口一起使用,int不是兼容类型。这就是编译器错误告诉你的:

error C2227: left of '->Release' must point to class/struct/union/generic type

          type is 'int *'

所以问题不在于您分配nullptr,而int没有Release()方法,CComPtr要求。 IUnknown(或派生)接口确实有Release()方法。

  

我们可以使用任何方法来检查CComPtr是否拥有任何对象吗?像if (myint == nullptr)这样的调用是否足以检查这个智能指针是否没有任何对象?

如果您更仔细地阅读CComPtr documentation,则会看到CComPtr来自CComPtrBase,其中operator!()operator T*()和{{1}运算符(所以operator==()行为像原始指针一样),以及CComPtr方法:

IsEqualObject()

int _tmain(int argc, _TCHAR* argv[])
{
    CComPtr<IUnknown> myUnk = nullptr;
    if (!myUnk) { // calls myUnk.operator!() ...
        std::cout << "null" << std::endl;
    else
        std::cout << "not null" << std::endl;
    }
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    CComPtr<IUnknown> myUnk = nullptr;
    if (myUnk) { // calls myUnk.operator IUnknown*() ...
        std::cout << "not null" << std::endl;
    else
        std::cout << "null" << std::endl;
    }
    return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
    CComPtr<IUnknown> myUnk = nullptr;
    if (myUnk == nullptr) { // calls myUnk.operator==(IUnknown*) ...
        std::cout << "null" << std::endl;
    else
        std::cout << "not null" << std::endl;
    }
    return 0;
}