1 设计思路
#include "istring.h"class IAnyInterface{ virtual void *DynamicCast(const char *psz)=0; virtual void DuplicatePointer()=0; virtual void DestroyPointer()=0;};class IString{ virtual void Delete()=0; virtual const char*Find(const char *psz)=0; virtual int Length()=0;};// 对象的接口不能发生变化, 如果接口中需要增加新的方法,可以派生出新的接口来class IString2 : public IString{ virtual char FindAt(int index)=0;};// 完全增加新的功能class IPersist{ virtual void Delete()=0; virtual void Save(const char *pszFile)=0; virtual void Load(const char *pszFile)=0;};class CMyString : public IString2, public IPersist, public IAnyInterface{private: char *m_psz; long m_refcount;public: CMyString(const char * psz); ~CMyString(); void DuplicatePointer(); void DestroyPointer(); void *Dynamic_cast(const char *); const char*Find(const char *psz); int Length(); char FindAt(int index); void Save(const char *pszFile); void Load(const char *pszFile);};
CMystring::CMyString(const char * psz) : m_psz( new char[psz ? strlen(psz)+1 :1]), m_refcount(0) { if ( psz ) strcpy(m_psz,psz); else m_psz[0] = 0;}void CMyString::DestroyPointer() { if (0<m_refcount) m_refcount--; if (0==m_refcount) delete this;}void CMyString::DuplicatePointer() { m_refcount++;}// 接口转换时刻相当于接口复制void *CMyString::Dynamic_cast(const char *psz) { void *p = NULL; if (strcmp(psz,"IString")==0) p = static_cast<IString *>(this); else if (strcmp(psz,"IString2")==0) p = static_cast<IString2 *>(this); else if (strcmp(psz,"IPersist")==0) p = static_cast<IPersist *>(this); if (NULL!=p) m_refcount++; return p;}
// 修改创建函数, 让创建函数也正确地维护引用计数extern "C" void *CreateString(const char *psz, const char *pszinterface) { void *pret = NULL; CMyString *p = new CMyString(psz); if (NULL!=p) { pret = p->Dynamic_cast(pszinterface); if (NULL==pret) delete p; } return pret;}
void main() { IString *p = CreateString("Hello"); if (p) { IString2 *p2; IPersist *p3; const char*psz = p->Find("llo"); int n = p->Length(); if ((p2=(IString2 *)p->Dynamic_cast("IString2"))) { char c = p2->FindAt(3); p2->DestroyPointer(); } if ((p3=(IPersist *)p->Dynamic_cast("IPersist"))) { p3->Save("c:\\temp\\str.txt"); p3->DestroyPointer(); } p->DestroyPointer(); }};
2 其他要考虑的问题
- Dll什么时候被卸载?
- 如何标识一个接口?字符串?
- 线程安全?
- 如何标识一个对象?对象的身份?
- 跨进程?跨机器?对象环境?
- ……