按照自己的使用习惯, 构造了一个智能指针.
一. 深/浅拷贝的智能指针
#include "stdafx.h"
// 深拷贝的智能指针
// 1. 手动/自动构造对象.
// 2. 自动深度赋值
// 3. 自动释放对象(对象内部资源对象自己负责)
// 浅拷贝的智能指针
// 1. 手动/自动构造对象.
// 2. 只是简单的指针拷贝.
// 3. 使用者自己管理指针共用问题.
template <class T, bool t_bDeep = true>
class CHYPtr
{
public:
CHYPtr()
: m_p(0)
{}
CHYPtr(const CHYPtr<T, t_bDeep>& hyDeepPtr)
: m_p(0)
{
*this = hyDeepPtr;
}
CHYPtr(const T t)
: m_p(0)
{
*this = t;
}
CHYPtr(T *t)
: m_p(t)
{}
~CHYPtr()
{
Release();
}
void Release()
{
if(0 != m_p)
{
delete m_p;
m_p = 0;
}
}
void Init()
{
if(0 == m_p)
{
m_p = new T;
}
}
void SetNULL()
{
if(true == t_bDeep)
{
Release();
}
else
{
m_p = 0;
}
}
T& operator*()
{
return *m_p;
}
T* operator->()
{
return m_p;
}
CHYPtr<T, t_bDeep>& operator=(const CHYPtr<T, t_bDeep>& hytr)
{
if(true == t_bDeep)
{
*this = *(hytr.m_p);
}
else
{
*this = hytr.m_p;
}
return *this;
}
CHYPtr<T, t_bDeep>& operator=(const T& t)
{
Init();
*m_p = t;
return *this;
}
CHYPtr<T, t_bDeep>& operator=(T* t)
{
Release();
m_p = t;
return *this;
}
private:
T *m_p;
};
template <class T>
class CHYDeepPtr
{
public:
CHYDeepPtr()
: m_p(0)
{}
CHYDeepPtr(const CHYDeepPtr<T>& hyDeepPtr)
: m_p(0)
{
*this = hyDeepPtr;
}
CHYDeepPtr(const T t)
: m_p(0)
{
*this = t;
}
CHYDeepPtr(T *t)
: m_p(t)
{}
~CHYDeepPtr()
{
Release();
}
void Release()
{
if(0 != m_p)
{
delete m_p;
m_p = 0;
}
}
void Init()
{
if(0 == m_p)
{
m_p = new T;
}
}
T& operator*()
{
return *m_p;
}
T* operator->()
{
return m_p;
}
CHYDeepPtr<T>& operator=(const CHYDeepPtr<T>& hyDeepPtr)
{
*this = *hyDeepPtr.m_p;
return *this;
}
CHYDeepPtr<T>& operator=(const T& t)
{
Init();
*m_p = t;
return *this;
}
CHYDeepPtr<T>& operator=(T* t)
{
Release();
m_p = t;
return *this;
}
private:
T *m_p;
};
template <class T>
class CHYShallowPtr
{
public:
CHYShallowPtr()
: m_p(0)
{}
CHYShallowPtr(const CHYShallowPtr<T>& hyShallowPtr)
: m_p(0)
{
*this = hyShallowPtr;
}
CHYShallowPtr(const T t)
: m_p(0)
{
*this = t;
}
CHYShallowPtr(T *t)
: m_p(t)
{}
~CHYShallowPtr()
{
Release();
}
void Release()
{
if(0 != m_p)
{
delete m_p;
m_p = 0;
}
}
void Init()
{
if(0 == m_p)
{
m_p = new T;
}
}
void SetNULL()
{
m_p = 0;
}
T& operator*()
{
return *m_p;
}
T* operator->()
{
return m_p;
}
CHYShallowPtr<T>& operator=(const CHYShallowPtr<T>& hyShallowPtr)
{
*this = hyShallowPtr.m_p;
return *this;
}
CHYShallowPtr<T>& operator=(const T& t)
{
Init();
*m_p = t;
return *this;
}
CHYShallowPtr<T>& operator=(T* t)
{
Release();
m_p = t;
return *this;
}
private:
T *m_p;
};
/////////////////////////////////////////////////////////////////////////////////
struct STTest
{
STTest()
: m_d(0.0)
{}
STTest(double d)
: m_d(d)
{}
STTest(const STTest& stTest)
{
*this = stTest;
}
~STTest()
{}
STTest& operator=(const STTest& stTest)
{
m_d = stTest.m_d;
return *this;
}
double m_d;
};
int _tmain(int argc, _TCHAR* argv[])
{
CHYPtr<int> pInt1; // 调用: CHYDeepPtr()
CHYPtr<int> pInt2(new int(222)); // 调用: CHYDeepPtr(T *t)
CHYPtr<int> pInt3(333); // 调用: CHYDeepPtr(const T t)
CHYPtr<int> pInt4(pInt3); // 调用: CHYDeepPtr(const CHYDeepPtr<T>& hyDeepPtr)
pInt1 = pInt2; // 调用: CHYDeepPtr<T>& operator=(const CHYDeepPtr<T>& hyDeepPtr)
pInt3 = 444; // 调用: CHYDeepPtr<T>& operator=(const T t)
pInt1 = new int(555); // 调用: CHYDeepPtr<T>& operator=(T* t)
*pInt3 = 555; // 调用: T& operator*()
CHYPtr<STTest> pSTTest1; // 调用: CHYDeepPtr()
CHYPtr<STTest> pSTTest2(new STTest(222.0)); // 调用: CHYDeepPtr(T *t) | STTest(double d)
CHYPtr<STTest> pSTTest3(333); // 调用: CHYDeepPtr(const T t) | STTest(double d)
CHYPtr<STTest> pSTTest4(pSTTest3); // 调用: CHYDeepPtr(const CHYDeepPtr<T>& hyDeepPtr)
*pSTTest2 = *pSTTest3; // 调用: T& operator*() | STTest& operator=(const STTest& stTest)
pSTTest2->m_d = pSTTest3->m_d; // 调用: T* operator->() | double的赋值
// 赋值为0, 自动释放内部的内存
pSTTest2 = 0; // 调用: CHYDeepPtr<T>& operator=(T* t)
//// 浅拷贝只能指针一定要避免共享指针问题
CHYPtr<int, false> pIntF1;
CHYPtr<int, false> pIntF2(new int(222));
CHYPtr<int, false> pIntF3(333);
CHYPtr<int, false> pIntF4(pIntF3); // 浅拷贝中, 是共享指针的. 释放的时候一定要注意
pIntF1 = pIntF2; // 浅拷贝中是共享指针
pIntF2.SetNULL();
pIntF3 = 444;
pIntF1 = new int(555);
*pIntF3 = 555;
// 这里一定要注意, pIntF4和pIntF3是共享指针的
pIntF3.SetNULL();
return 0;
}