为什么智能指针还需要 Release呢,智能指针不是不需要进行管理引用计数了吗,为什么还需要程序员来release?
原因是,智能指针对象在对象销毁时释放所指向的接口,但如果没有在函数退出前,你销毁了com库,那就需要提前来Release它。
如:
::CoInitialize( NULL ); //如果在这里初始化,则要注意智能指针的释放
CComQIPtr < IFun, &IID_IFun > spFun;
HRESULT hr = spFun.CoCreateInstance( CLSID_Fun );
ASSERT( SUCCEEDED( hr ) );
// 为简单起见,不再用if判断HRESULT了。并且不再对IFun::Add()调用举例
CComBSTR s1( "Hello" ), s2( " world" ), s3;
hr = spFun->Cat( s1, s2, &s3 );
ASSERT( SUCCEEDED( hr ) );
CString sMsg( s3 );
AfxMessageBox( sMsg );
// spFun->Release(); // 大错特错!!!!!
spFun.Release(); // 正解
::CoUninitialize(); //如果不是在这里销毁初始化,那么可以没有上面的Release,这样,在函数退出时,它就可以自动的销毁对接口的引用。
下面一段话来自 wpf2006的博客
如果在C++中调用com组件,可以使用智能指针简化需要做的工作。智能指针还可以解决编程当中的一些问题,比如手工处理接口的引用计数很容易出错,往往非常难以查找,用智能指针就不会出现这种情况。下面总结一下有关智能指针的要点。
在实现上,智能指针是一个C++类,它封装了一个com接口指针。在概念上,智能指针可以如同接口指针一样来使用,但又有所区别。我们还是从使用概念出发来认识它。
一个智能指针对应一个接口指针。定义智能指针并用对应接口指针初始化以后,可以通过智能指针的->调用接口中的函数,可以用接口指针给智能指针赋值,改变它对应的接口。这是基本的两个用法,都是通过重载相应运算符实现的,还有其他运算符可以重载,使智能指针和接口指针更为相似。那么好处在哪里呢?智能指针在使用上无关引用计数,在它的实现中就要解决这个问题。一个智能指针就是对接口的一个引用,在初始化时需要调用接口的AddRef(),析构时调用Release(),智能指针作为栈上的C++对象总会被析构,就是在发生异常时也是如此,所以对应接口总会被释放。当智能指针的接口指针被改变时,表示不再引用前一个接口和开始引用后一个接口,所以要对前者调用Release(),对后者调用AddRef()。无关引用计数是智能指针与接口指针的基本区别,在使用上表现为不可通过智能指针调用接口的Release()。在智能指针析构时释放接口是一种整体上的方案,可以保证接口的释放,但是有时不能做到及时释放,所以也要提供途径让程序员主动释放智能指针对应的接口。可以由智能指针本身实现一个类似Release()的函数。智能指针本身定义的函数通过点记法调用。
最后总结一下,智能指针对应接口指针,它与接口指针高度相似,又有重要的区别。相似是为了便于程序员使用,区别则是因为智能指针接管了引用计数的处理。相似体现在:1). 可以通过智能指针的->调用接口中的函数;2). 可以用接口指针给智能指针赋值;等等。区别体现在:1). 不能通过智能指针调用接口的Release();2). 可以通过点记法调用智能指针本身定义的函数,特别是供程序员主动释放所封装接口的函数。