您的位置:首页 > 其它

有效的使用和设计COM智能指针——条款26:自动查询接口带来方便同时也潜藏危机

2011-09-22 09:02 387 查看

条款26:自动查询接口带来方便同时也潜藏危机

更多条款请前往原文出处:http://blog.csdn.net/liuchang5

如果你对条款5中_com_ptr_t简介中的内容还有印象的话,那你会很清楚的记得这样一些东西。_com_ptr_t会自动帮我们查询适当接口,优点很明显,它简化了我们的开发,而CComPtr却没有这么做。理由是什么?还是先看一段代码吧:

_COM_SMARTPTR_TYPEDEF(IA, __uuidof(IA));
_COM_SMARTPTR_TYPEDEF(IB, __uuidof(IB));
void func(IAPtr spIA,IBPtr spIB);
HRESULT COM_PTR_TSmartPointer()
{
IAPtr spIA(CLSID_MYCOMPONENT1);
IBPtr spIB(CLSID_MYCOMPONENT2);
...
func(spIB,spIA); // 哦~ 参数传错了,程序却可能编译通过。
}

哦~ 在分析这种情况之前,你可能已经注意到了我们有违反条款10中提到的建议“让接口指针仅存在于函数参数中”。是的,我们确实违反了,这也体现出违反这一条款的另一个负面效应。但这仅仅是我给读者的一些忠告和建议。你能遵守,那必然是好的,上面的情况也不会存在。但谁能保证其他人编写的所有程序都严格遵守这些忠告呢?

我们现在站在设计者的角度来看这一问题,它或许就成为设计中的缺陷了。

在观察一下上面代码,spIA指向的组件和spIB的组件可以相互查询接口。那么,程序继续执行下去。但spIA和spIB指向的确是两个不同的组件。你无法保证他们实现相同。因此在两个接口可以互相查询到对方的情况下,如果发生了参数传递错误,那么因为组件实现的不同,程序执行结果却可能有相当大的差异。错误发生了,它或者非常之严重。但在bug发生之后,你如不过不一行一行的阅读代码,查看每个参数是否传递正确,别指望这个错误会自动蹦出来。

考虑另外一种情况,若spIA和spIB两个接口无法查询到对方呢?_com_ptr_t的实现方式是,抛出一个讨厌的臭鸡蛋(异常)~若你没有对异常进行捕获,那程序直接崩掉,这是最简单也是最乐观的情况。如果,你的上层调用者捕获到异常(它或许是由你自己来编写的,也或者是其他人),他会进行何种错误处理?还是悄悄把异常吞掉?程序的路径又会做何种改变?这都不得而知。

核心问题是什么?自动查询接口功能的引入使得COM接口变成了弱类型的。试想一下如果你有一个名为BaseType组件,他实现了IFloat,IInt,IDouble,IString,IBigDecimal等接口类型。而不同接口却可以相互查询。后果是,天知道当IInt接口查询IString接口后,他内部的数值是以itoa的方式进行转换,还是直接转换为相应的ASCII码?又有谁来承担float查询到double后精度丢失的问题?

最后,一分为二的看待一下这个问题:自动查询接口功能方便了我们的开发,但却同时使得可以相互查询的COM接口呈现出若类型语言的弊端。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐