该例子中的智能指针与标准库及boost的类似,只是多了一些智能指针与原始指针的比较操作,转换操作也值得学习看一下
智能指针看得例子比较多了,下面例子中有部分写代码时觉得比较有意思的注释
smartptr.h
#pragma once
//////////////////////////////////////////////////////////////////////////
//#include "SmartPtrsImpl.h"
template<typename T>
class CSmartPtrs
{
class SmartPtrPrivate
{
void operator delete(void*); // 重载delete并且不实现,防止将CSmartPtrs转换为SmartPtrPrivate后进行delete操作
};
public:
explicit CSmartPtrs(T* pt)
:pT_(pt)
{
}
~CSmartPtrs()
{
if (NULL != pT_)
{
delete pT_;
}
}
T* operator->()
{
return pT_;
}
T& operator*()
{
return *pT_;
}
bool operator!()
{
return pT_ == NULL;
}
// 智能指针与智能指针比较
inline bool operator == (const CSmartPtrs& rhs)
{
return pT_ == rhs.pT_;
}
// 智能指针与原始指针比较
inline friend bool operator == (const CSmartPtrs& lhs, const T* rhs)
{
return rhs == lhs->pT_;
}
// 原始指针与智能指针比较
inline friend bool operator == (const T* lhs, const CSmartPtrs& rhs)
{
return lhs == rhs.pT_;
}
// 同样需要实现 != 在此省略
// 原始的可以转换的指针比较
// 智能指针与原始指针(可以转换的原始指针)比较
template<class U>
inline bool operator==(const U* rhs)
{
return pT_ == rhs ;
}
// 原始指针与智能指针(可以转换的原始指针)比较
template<class U>
inline friend bool operator==(const U* lhs, const CSmartPtrs<T>& rhs)
{
return lhs == rhs.pT_;
}
// 两个不同类型的智能指针比较
template<class U>
inline bool operator==(CSmartPtrs<U>& rhs)
{
return pT_ == rhs.pT_;
};
// 解决Smart<T> pa; if(pa)问题
// 如果使用operator T*()的方式将它默认转换为T*是可以解决,但是开发者容易错误的使用隐私转换
// 不小心delete pa那就完蛋了。可以再写个operator void*()的方式让delete有歧义。delete不知道该选用哪个去delete。
//operator T*(){return pt_};
//operator void*(){return NULL;}
// 转换成一个内部类,只用作()比较操作
operator SmartPtrPrivate*()
{
if (!pT_)
{
return 0;
}
static SmartPtrPrivate smartprivate;
return &smartprivate;
}
private:
T* pT_;
};
//测试代码
void CTestSmartPtrs::Test()
{
CSmartPtrs<CTest> aa1(new CTest);
CSmartPtrs<CTest> aa2(new CTest);
CTest* aa3 = NULL;
if (aa1)
{
}
if (!aa2)
{
}
if (aa1 == aa2)
{
}
if (aa1 == aa3)
{
}
if (aa3 == aa1)
{
}
CSmartPtrs<CTestBase> bb1(new CTest);
CSmartPtrs<CTest> bb2(new CTest);
CTest* bb3 = new CTest;
if (!bb1)
{
}
if (bb1 == bb3)
{
}
if (bb3 == bb1)
{
}
// if (bb1 == aa2)
{
}
}