有效的使用和设计COM智能指针——条款24:努力使得接口容易被使用而不易被误用。
2011-09-21 11:06
429 查看
条款24:努力使得接口容易被使用而不易被误用。
更多条款请前往原文出处:http://blog.csdn.net/liuchang5你可能会发现_com_ptr_t并没有禁止用户调用其持有的接口指针的Release()函数和AddRef()函数。如果遇到一个粗心的程序员,可能程序就悲剧了:
ICalculatorPtr spCalculator(CLSID_CALCULATOR); ... spCalculator->Release(); //哦~ 悲剧了~ 本意是调用 .Release()
如何来尽可能减少这种悲剧发生的可能信呢?或许你可以通过=NULL的方式来提前释放资源,而不会因为调用.Release()时手误而造成程序中的错误。(更多的关于=NULL和.Release的讨论可以参考条款22)
而CComPtr则巧妙屏蔽了这种不安全的操作。我们窥看一下他的代码,看看他是如何实现的。
template <class T> //ATL先声明了一个将AddRef和Release隐藏起来的类 class _NoAddRefReleaseOnCComPtr : public T { private: STDMETHOD_(ULONG, AddRef)()=0; STDMETHOD_(ULONG, Release)()=0; };
_NoAddRefReleaseOnCComPtr<T>* operator->() const throw() { ATLASSERT(p!=NULL); return (_NoAddRefReleaseOnCComPtr<T>*)p; //一个巧妙的返回值! }
当我们在CComPtr中做误操作时,编译就无法通过了:
CComPtr<ICalculator> spCalculator = NULL; spCalculator.CoCreateInstance(CLSID_CALCULATOR); ... spCalculator->Release(); //哦~ 悲剧了~ 本意是调用 .Release()
你可能不得不赞叹模版的强大,也同时感谢CComPtr开发者为我们做了如此周到的设想。但如果你是ATL的老用户,或者你手上ATL的版本极为古老的话。你可能看不到上面这样的设计。而->Release()的操作依旧被允许。
事实上,我并没有拿到更加古老的版本的ATL源码,在我的机器上最老的版本是VC6中自带的ATL3.0。而他也已经实现了这种操作来避免用户的误操作。但我们从古老的MSDN文档上仍然看出,在CComPtr中这种危险操作在以前是被允许的。截图为证【9】:
相关文章推荐
- 有效的使用和设计COM智能指针——条款19:在接口完满的前提下使之最小化。
- 有效的使用和设计COM智能指针——条款26:自动查询接口带来方便同时也潜藏危机
- 有效的使用和设计COM智能指针——条款11:以类型安全的方式创建资源和查询接口
- 有效的使用和设计COM智能指针——条款6:尽量以智能指针替换接口指针
- 有效的使用和设计COM智能指针——条款10:尽量减少智能指针和接口指针的混用
- 有效的使用和设计COM智能指针——条款20:安全的覆盖掉C++默默为我们编写的函数
- 有效的使用和设计COM智能指针——条款12:必要时使用attach() 和 detach()调整引用计数
- 有效的使用和设计COM智能指针——条款27:考虑__uuidof与uuid在关键字在不同编译器上的兼容问题
- 有效的使用和设计COM智能指针 ——条款13:必须提前释放COM组件时,别妄想智能指针帮你完成
- 有效的使用和设计COM智能指针——条款21:巧妙的将对象伪装成指针
- 有效的使用和设计COM智能指针——条款22:果断放弃二进制重用,而采用模版编写智能指针
- 有效的使用和设计COM智能指针——条款23:为例外条件准备应对策略。
- 有效的使用和设计COM智能指针——条款1:智能指针之前世今生
- 有效的使用和设计COM智能指针——条款14:有意识的限制智能指针的生命周期
- 有效的使用和设计COM智能指针——条款2:引用计数的是与非
- 有效的使用和设计COM智能指针 条款8:条款9:尽可能不将智能指针放置于堆上
- 有效的使用和设计COM智能指针—条款4:理解ATL的CComPtr提倡简单
- 有效的使用和设计COM智能指针——条款15:以原则中的优先级作为取舍的依据
- 有效的使用和设计COM智能指针——条款3:按照功能和实现原理选择合适的智能指针
- 有效的使用和设计COM智能指针 ——条款16:智能指针的引入不能违反COM引用计数规则