自己写的share_ptr + Arry 来制作CString共享版本

#include "MyStudyFile.h"
#include <crtdbg.h>
#include <boost/smart_ptr/shared_ptr.hpp>
int  strlength (const char * str)
{
	const char *eos = str;
	while( *eos++ ) ;
	return( eos - str - 1 );
}
char *  strcapend (char * dst,const char * src)
{
	char * cp = dst;
	while( *cp )cp++;
	while( *cp++ = *src++ ) ;
	return( dst );
}
char * __cdecl strcopy(char * dst, const char * src)
{
	char * cp = dst;
	while( *cp++ = *src++ );
	return( dst );
}
template<class T>
void SwapFun(T& left, T& right)
{
	T temp = left;
	left = right;
	right = temp;
}
template<class T>
class CArry
{
	typedef T ELEMENT_TYPE;
public:
	CArry(const ELEMENT_TYPE* pChar, int nSize)
		:m_iMaxSize(nSize), m_iCurentSize(nSize)
	{
		m_pVChar = new ELEMENT_TYPE[m_iMaxSize];
		ELEMENT_TYPE* pStart = m_pVChar;
		while (nSize --)
		{
			*pStart++ = *pChar++;
		}
	}
	CArry(const ELEMENT_TYPE* pChar, int nSize, int nMaxSize)
		:m_iMaxSize(nMaxSize), m_iCurentSize(nSize)
	{
		m_pVChar = new ELEMENT_TYPE[m_iMaxSize];
		ELEMENT_TYPE* pStart = m_pVChar;
		while (nSize --)
		{
			*pStart++ = *pChar++;
		}
	}
	CArry& Append(const ELEMENT_TYPE* pChar, int nSize)
	{
		if (nSize + m_iCurentSize <= m_iMaxSize)
		{
			ELEMENT_TYPE* pStart = m_pVChar+ m_iCurentSize;
			while(nSize --)
			{
				*pStart++  = *pChar++;
			}
		}
		else
		{
			CArry(m_pVChar, m_iCurentSize, nSize + m_iCurentSize).Swap(this);
			Append(pChar, nSize);
		}
	}
	CArry& Assign(const int posAfter, ELEMENT_TYPE* pChar, int nSize)
	{
		ELEMENT_TYPE* pStart = m_pVChar + posAfter;
		while(nSize --)
		{
			*pStart++ = *pChar++;
		}
	}
	~CArry()
	{
		delete[] m_pVChar;
	}
	operator ELEMENT_TYPE*()
	{
		return m_pVChar;
	}
	int GetSize()
	{
		return m_iCurentSize;
	}
private:
	void Swap(CArry& other)
	{
		SwapFun(m_pVChar, other.m_pVChar) ;
		SwapFun(m_iMaxSize, other.m_iMaxSize);
		SwapFun(m_iCurentSize, other.m_iCurentSize);
	}
	ELEMENT_TYPE* m_pVChar;
	int m_iMaxSize;
	int m_iCurentSize;
};
//共享的实现。
template<class T>
class ShareDataImp
{
	typedef T ElementType;

private:
	struct SharedData
	{
		SharedData(ElementType* p = NULL):m_p(p), nRef(1)
		{
		}
		void AddRef()
		{
			++ nRef;
		}
		void Release()
		{
			if (-- nRef == 0)
			{
				delete m_p;
				m_p = NULL;
			}
		}
		ElementType* GetPtr()
		{
			return m_p;
		}
		int GetCount()
		{
			return nRef;
		}
	private:
		ElementType* m_p;
		int nRef;
	};

public:
	ShareDataImp(ElementType* pstr = NULL) 
		: m_pData(new SharedData(pstr))
	{
	}
	~ShareDataImp()
	{
		m_pData->Release();

		if (m_pData->GetCount() == 0)
		{
			delete m_pData;
		}

		m_pData = NULL;
	}
	ShareDataImp(const ShareDataImp& _right)
		: m_pData(_right.m_pData)
	{
		m_pData->AddRef();
	}
	//释放对共享数据的所有权。
	void ResetAs(ElementType* p)
	{
		m_pData->Release();

		delete m_pData;

		m_pData = new SharedData(p);
	}
	ElementType* Get() const
	{
		return m_pData->GetPtr();
	}
private:
	SharedData* m_pData;
};


class CString
{
public:
	CString(char* pStr)
	{
		CArry<char>* pArry = new CArry<char>(pStr, strlength(pStr) + 1);
		m_shareData.ResetAs(pArry);
	}
	~CString()
	{
	}
	const char* cstr() const
	{ 
		return *(m_shareData.Get());
	}

	CString& Append(CString& strVal)
	{
		CString strRight(strVal.cstr());

		m_shareData.ResetAs(CloneData(GetLength() + strRight.GetLength() + 1));

		m_shareData.Get()->Assign(GetLength(), strRight.cstr(), strRight.GetLength() + 1);

		return *this;
	}
	CString& Append(char* pChar, int iLength)
	{
		m_shareData.ResetAs(CloneData(GetLength() + iLength + 1));

		m_shareData.Get()->Assign(GetLength(), pChar, iLength + 1);
	}

	CString& Assign(const CString& strVal)
	{
		m_shareData.ResetAs(strVal.CloneData(strVal.GetLength() + 1));

		return *this;
	}

	CString& Assign(char* pStr)
	{	
		m_shareData.ResetAs(new CArry<char>(pStr, strlength(pStr) + 1));

		return *this;
	}

	int GetLength() const
	{
		return m_shareData.Get()->GetSize() - 1;
	}
	
private:
	char* cstr()
	{
		return  *(m_shareData.Get());
	}

	CArry<char>* CloneData(int iSize) const
	{
		return new CArry<char>(cstr(), GetLength() + 1, iSize);
	}

	ShareDataImp<CArry<char>> m_shareData;
};

int main()
{
	CString* pVal = new  CString("121312");
	CString* pVa2 = new  CString(*pVal);
	CString* pVa3 = new  CString(*pVa2);
	CString* pVa4 = new  CString(*pVa3);
	delete pVal;
	delete pVa2;
	delete pVa3;
	delete pVa4;
	_CrtDumpMemoryLeaks();
}

 

你可能感兴趣的:(String)