设为首页 加入收藏

TOP

19.8.6 interface_cast_base
2013-10-07 15:07:22 来源: 作者: 【 】 浏览:64
Tags:19.8.6 interface_cast_base

19.8.6  interface_cast_base

这3个接口强制类仅仅负责使用恰当的策略类对它们的基类进行参数化,从而使某些特定的特性成为可访问的。实际上所有动作都发生在interface_cast_base之内,如程序清单19.19所示:

程序清单19.19

  1. template< typename I  
  2.           , typename R  
  3.           , typename X  
  4.           > 
  5. class interface_cast_base  
  6. {  
  7. protected:  
  8.   typedef I   interface_type;  
  9.   typedef R   release_type;  
  10.   typedef X   exception_policy_type;  
  11. protected:  
  12.   template <typename J> 
  13.   explicit interface_cast_base(J &j)  
  14.     : m_pi(do_cast(j))  
  15.   {}  
  16.   explicit interface_cast_base(interface_type pi)  
  17.     : m_pi(pi)  
  18.   {  
  19.     addref(m_pi);  
  20.   }  
  21.   ~interface_cast_base()  
  22.   {  
  23.     if(NULL != m_pi)  
  24.     {  
  25.       release_type()(m_pi);  
  26.     }  
  27.   }  
  28.   static interface_type do_cast(LPUNKNOWN punk)  
  29.   {  
  30.     interface_type  pi;  
  31.     if(NULL == punk)  
  32.     {  
  33.       pi = NULL;  
  34.     }  
  35.     else  
  36.     {  
  37.       REFIID  iid = IID_traits<interface_type>().iid();  
  38.       HRESULT hr  = punk->QueryInterface(iid,  
  39.                                  reinterpret_cast<void**>(&pi));  
  40.       if(FAILED(hr))  
  41.       {  
  42.         exception_policy_type()(hr, iid);  
  43.         pi = NULL;  
  44.       }  
  45.     }  
  46.     return pi;  
  47.   }  
  48.   interface_type const  &get_pointer_();  
  49.   interface_type        get_pointer_() const;  
  50. private:  
  51.   interface_type const  m_pi;  
  52. private:  
  53.   . . . // 拷贝构造函数和拷贝赋值操作符不可访问  
  54. };  

上边的代码中有几点值得注意。首先,所有方法都是受保护的(protected),因此它们不能被外界直接使用,从而也就避免了误用,它们只能被派生类使用。其次,正如先前我们曾讨论过的,构造函数具有模板和非模板两个版本,这样一来既支持了泛用性又兼顾了效率。最后,接口指针如果非空的话就会被交给参数化的release_type仿函数进行释放(见interface_cast_base的析构函数),从而按照release_type策略类要求的方式进行释放(与否)。

那么现在就剩下静态方法do_cast()了。do_cast()是所有幕后工作的主使,interface_cast_base会在模板构造函数里调用do_cast()来尝试进行强制。如果给定的接口指针非空,do_cast()就会调用该指针所指接口的QueryInterface()方法来获取用户请求的接口。如果获取成功的话,新的接口将会返回给客户端,如果失败,则调用exception_policy_type仿函数。而在调用exception_policy_type仿函数之后,如果exception_policy_type什么事情都不做,   pi就会被置为NULL然后返回给客户端。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇19.2 C++中的强制 下一篇19.8.3 interface_cast_test

评论

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