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什么时候被卸载?
- 如何标识一个接口?字符串?
- 线程安全?
- 如何标识一个对象?对象的身份?
- 跨进程?跨机器?对象环境?
- ……