CComPtr用法
COM接口指针很危险,因为使用过程中需要每一个使用者都要严格并且正确的AddRef和Release,一旦出现问题,就会造成对象不能被正常释放,或者对象被重复删除,造成程序崩溃。所以使用COM接口,必须小心翼翼才行。
但是,即使所有的代码中,都正确的AddRef和Release,也不一定能保证万无一失,例如:
void SomeApp( IHello * pHello )
{
IHello* pCopy = pHello;
pCopy->AddRef();
OtherApp();
pCopy->Hello();
pCopy->Release();
}
看起来好像无懈可击,但是假设OtherApp中抛出了异常,那么pCopy->Release不就被跳过去了吗?
幸好,所有的问题都从简单到复杂,再从复杂到简单的,因为我们有CComPtr!
CComPtr被称为智能指针,是ATL提供的一个模版类,能够从语法上自动完成AddRef和Release。(源代码在atlbase.h中)
CComPtr的用法很简单,以IHello*为例,将程序中所有接口指针类型(除了参数),都使用CComPtr<IHello> 代替即可。即程序中除了参数之外,再也不要使用IHello*,全部以CComPtr<IHello>代替。
CComPtr的用法和普通COM指针几乎一样,另外使用中有以下几点需要注意。
1. CComPtr已经保证了AddRef和Release的正确调用,所以不需要,也不能够再调用AddRef和Release。
2. 如果要释放一个智能指针,直接给它赋NULL值即可。(这一点要牢记曾因为没有设置为null而出错)
3. CComPtr本身析构的时候会释放COM指针。
4. 当对CComPtr使用&运算符(取指针地址)的时候,要确保CComPtr为NUL。(因为通过CComPtr的地址对CComPtr赋值时,不会自动调用AddRef,若不为NULL,则前面的指针不能释放,CComPtr会使用assert报警)
以刚才的程序为例:
void SomeApp( IHello * pHello )
{
CComPtr<IHello> pCopy = pHello;
OtherApp();
pCopy->Hello();
}
由于pCopy是一个局部的对象,所以即使OtherApp()抛出异常,pCopy也会被析构,指针能够被释放。
如果不想在程序临近发布前,还因为COM指针的引用计数造成崩溃的话,就牢记这一点吧:程序中除了参数之外,不要直接使用COM指针类型,一定要全部以CComPtr<IXXX>代替。
CComPtr用法的更多相关文章
- IntersectRect、wcsrchr、CComPtr、GetFileAttributes
IntersectRect 两矩形相交形成的新矩形 The IntersectRect function calculates the intersection of two source re ...
- IDispatch接口 - GetIDsOfNames和Invoke(转)
IDispatch接口是COM自动化的核心.其实,IDispatch这个接口本身也很简单,只有4个方法: IDispatch : public IUnknown { public: virtual H ...
- EditText 基本用法
title: EditText 基本用法 tags: EditText,编辑框,输入框 --- EditText介绍: EditText 在开发中也是经常用到的控件,也是一个比较必要的组件,可以说它是 ...
- jquery插件的用法之cookie 插件
一.使用cookie 插件 插件官方网站下载地址:http://plugins.jquery.com/cookie/ cookie 插件的用法比较简单,直接粘贴下面代码示例: //生成一个cookie ...
- Java中的Socket的用法
Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...
- [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法
一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...
- python enumerate 用法
A new built-in function, enumerate() , will make certain loops a bit clearer. enumerate(thing) , whe ...
- [转载]Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结
本文对Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法进行了详细的总结,需要的朋友可以参考下,希望对大家有所帮助. 详细解读Jquery各Ajax函数: ...
- 【JavaScript】innerHTML、innerText和outerHTML的用法区别
用法: <div id="test"> <span style="color:red">test1</span> tes ...
随机推荐
- 对DNSPOD添加域名解析的一些见解
1.主机记录这步比较简单,输入“www”表示比较常规的域名例如www.abc.com,“@”表示abc.com,“ * ”表示泛解析,匹配所有*.abc.com的域名. 2.记录类型这步,一般常用A记 ...
- Objective-C学习篇05—Foundation框架简介
iOS中所谓的框架,说到底就是一个目录,iOS提供了很多我们可以在应用程序中调用的框架.许多应用程序都使用了如Foundation.UIKit和Core Graphics这些框架.根据你为应用程序选择 ...
- web开发 关于src跳转
src跳转看传递的参数值,如果参数值一样就不会再次跳转,也不会向后台的服务器提供request. 想要随时都能跳转可以传递不同的参数,如 onClick="this.src='http:// ...
- cas配置全攻略(转)
转:http://www.blogjava.net/tufanshu/archive/2011/01/21/343290.html 经过将近两天的测试,参考众多网友的贡献,终于完成了对cas的主要配置 ...
- 网络编程Socket之UDP
服务器端实现步骤: 1. 创建 DatagramSocket,指定端口号 2. 创建 DatagramPacket 3. 接收客户端发送的数据信息 4. 读取数据 package cn.jmu.edu ...
- 【cogs247】售票系统
[问题描述] 某次列车途经C个城市,城市编号依次为1到C,列车上共有S个座位,铁路局规定售出的车票只能是坐票, 即车上所有的旅客都有座.售票系统是由计算机执行的,每一个售票申请包含三个参数,分别用O. ...
- [转]python集合set
Python中集合set是基本数据类型的一种,它有可变集合(set)和不可变集合(frozenset)两种.创建集合set.集合set添加.集合删除.交集.并集.差集的操作都是非常实用的方法. 来源网 ...
- $_CFG = load_config(); /* 载入系统参数 */
ecshop 中$_CFG数组主要是放置一些系统参数,并且全站共享的数据,在使用的时候,ecshop里面常常以$GLOBALS['_CFG']全局变量的模式来处理. ecshop 的$GLOBALS[ ...
- Android 判断当前网络连接类型
实际应用开发时,如果存在需要用户获取大量数据的情况,最好是先判断下网络类型,提示用户当前的网络类型,是否需要连接Wifi,etc.(手机流量太贵啦,当然土豪是无视这玩意的, (/ □ \)). 定义网 ...
- DropzoneJS 可以拖拽上传的js库
介绍 可以拖拽上传的 js库 网址 http://www.dropzonejs.com/ 同类类库 1.jquery.fileupload http://blueimp.github.io/jQu ...