设为首页 加入收藏

TOP

19.8.3 interface_cast_test
2013-10-07 15:07:19 来源: 作者: 【 】 浏览:60
Tags:19.8.3 interface_cast_test

19.8.3  interface_cast_test

我们将会在第七部分看到,不管你的错误处理是基于异常还是基于返回值,你总免不了要在某个地方对错误作出响应(处理)。所以,倘若我们使用的是interface_cast_addref,我们就必须检查它的返回值是否为NULL,而在使用interface_cast_noaddref的时候,我们则需要捕获bad_interface_cast异常。由于COM是一个二进制接口,异常不能跨连接单元被捕获(见第9章),所以我们可能会在该强制的周围看到许多try-catch块。

COM的一致性规则[Box1998]要求,如果一个实例曾对QueryInterface()调用返回过某个给定的接口,它就必须在它的整个生命期中都具有这种行为。由此我们引出第三个接口强制interface_cast_test。本质上这是一个假装成逻辑垫片(Logical Shim)的强制(见20.3节)。所谓逻辑垫片,即是用在条件表达式中的一种垫片。interface_cast_test可以用来确保某个对应的interface_cast_noaddref不会抛出异常,或者,对于interface_cast_addref来说,则是确保它不会返回NULL。但它真正派上用场的地方其实是跟非临时性的interface_cast_noaddref结合使用的时候,像这样:

  1. IUnknown  *punk =  . . .;  
  2. if(interface_cast_test<IThing*>(punk))  
  3. {  
  4.   interface_cast_noaddref<IThing*>  thing(punk);  
  5.   thing->Method1();  
  6.   . . .  
  7.   thing->MethodN();  
  8. } // thing的析构函数会负责释放它引用的接口  

当然,还有另一种做法,即我们创建一个非临时的thing实例,然后如果punk不能被转换为IThing*,我们就捕获它抛出的异常,殊途同归。然而在实际中,COM组件的创建其实是一个轻量级的举动,有时甚至是在没有C/C++(www.cppentry.com)运行时库支持的情况下[Rect1999]。在这样的场合下,interface_cast_noaddref缺省抛出的异常可以(通过预处理指令)设置为实际不抛出异常,从而允许上面的代码既简洁又安全,同时不失其轻量级本色。这在C++(www.cppentry.com)里可能被认为是不"妥当"的做法,但我们是不完美主义的实践者,而在当前(技术上的)环境的限制下这又确实能够给代码质量带来实质性的提升,所以我们选择采用它。

我拥护Kernighan和Pike的意见[Kern1999],相信异常应该仅被用在那些真正意料之外的情况下,因此我在大多数场合下都更倾向于采用这个策略。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇19.8.6 interface_cast_base 下一篇19.8.2 interface_cast_noaddref

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: