有效的使用和设计COM智能指针——条款22:果断放弃二进制重用,而采用模版编写智能指针

来源:互联网 发布:王氏配餐软件 编辑:程序博客网 时间:2024/05/23 00:03

条款22:果断放弃二进制重用,而采用模版编写智能指针

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

你看到了很多智能指针是用模版编写的,它们能让智能指针应用于更多的类型之上。这个可以理解。但是所有接口从IUnknown“单源继承”的概念会让你有放弃模版这种复杂技术的念头。你或许会想,如果那样的话,我们就能塑造出一个二进制级别可重用的智能指针,而且没有模版的参与,可以减少编写过程中一些复杂的特化过程。看看下面这个智能指针是否适用:

class MyComSmartPtr{public:    MyComSmartPtr(IUnknown *pI) : m_pI(pI){};    ~MyComSmartPtr()    {        if (m_pI)            m_pI->Release();    };private:    IUnknown *m_pI;};

他已经是个稍微合格的资源管理对象了。而且没有讨厌的模版,确实减少了复杂度,也使得代码在二进制层面上能得以复用(你可能把他编译成DLL,而模版却必须将源码放在头文件中)。

让我们回顾一下条款7,智能指针除了完成资源管理的功能之外还得像个指针。那么让我们先给他加上一个->操作符。

IUnknown* operator->() const throw(){    ATLASSERT(p!=NULL);    return IUnknwon* m_pI;}

->来返回一个IUnknown的指针确实让人觉得有点不自在,因为你可能会需要一个向下转型来实现某些功能。

func(IMyinteface *pInterface){    MyComSmartPtr<IMyInterface*> spMyInterface(pInterface);    dynamic_cast<IMyInterface*>(spMyInterface)->DoSomething(); //语法纠结且不安全}


上面这个纠结的用法,可能足以让你放弃掉依赖从IUnknown的“单源继承”特性来实现一套在二进制级可重用的智能指针的想法。RTTI的开销、类型安全性以及运行时可能产生的错误都是不容乐观的。同时模版相对于使用时的向下转型或许要简单和安全得多。知道如上这些,我想你不会再拒绝模版了~