使用CsmartInterface有两个主要的规则。首先,不要在CsmartInterface对象上调用Release。
void Draw() { CSmartInterface<idraw> SIDraw; CoCreateInstance(...,IID,_IDraw, (void**)&SIDraw) ; SIDraw->Draw() ; SIDraw->Release() ; // Will compile, but is a bug. } |
当SIDraw->Release被调用,则SIDraw->m_pl被释放。当SIDraw->m_PI的析构函数被调用时,只要接口还没有 被释放,SIDraw->m_PI将再一次被释放。这个问题并不是难以调试,如果你有关于引用计数的问题,你可以查找一下所有发生的Release。另一个途径是适用#define Release BOGUS_DO_NOT_CALL_RELEASE!但是这样使用Release则会产生一个错误。当然,如果你的应用程序里其他带有"Release"这个词的函数(就象许多Win32应用程序接口[APIS],这个方法将行不通。
第二条规则是避免把CsmartInterface对象使用成指针。如果你这样做,情况将很混乱:
CSmartInterface<isimple>* pSISimple = new CSmartInterface<isimple>(m_pISimple) ; (*pSISimple)->Inc() ; delete pSISimple ; |
使用typedef将能将这种情况稍稍整理一下:
typedef CSmartInterface<isimple> CSmartISimple ; CSmartISimple* pSISimple = new CSmartISimple(m_pISimple) ; (*pSISimple)->Inc() ; delete pSISimple ; |
不过,这并不能改变(*PSISimple)->Incc);实际上不是非常简单的事实。
如果我们考虑一下为什么我们想要一个指向接口的指针,我们可能会发现环绕着问题的一条路。我们想在程序中的一些任意点释放接口--而不是要等到CsmartInterface已经不在范围之内。那么问题将变成我们如何释放包含在CsmartInterface中的接口。答案非常的简单:SISimple=NULL;虽然这是一句很典型的C代码,但是这儿到底发生了什么却一点都不明显。
pISimple->Release() ; and delete pSISimple ; |
都是更明显地指示对象已经消失的方法。