智能指针比较多,但是用的比较多的还是auto_ptr。
auto_ptr被引入的初衷是为了解决堆内存泄露问题。
即new出对象后,忘记deleted掉导致的内存泄露。
auto_ptr使用方法非常简单:将new出的堆对象指针作为初值传给一个auto_ptr对象即可,
而后无需手动进行delete操作,而由auto_ptr对象在其生命周期结束后自动调用。
下面是根据auto_ptr的源码自己写的一个简化版,
主要注意下常用的成员函数如release() , reset(), get()的实现原理,都比较简单。
另外,源代码中其所有的成员变量都申明为inline,这里偷懒未进行标示。
备注:上面的说法有误。“inline只是对编译器的一个申请,不是强制命令。这项申请可以隐喻提出,也可以明确提出。
隐喻方式是将函数定义于class定义式中。”,因此,只要在类中进行定义的成员函数,加或不加inline关键字编译器都会对其inline处理。
inline的知识可以参考:<Effective C++> 条款30:透彻了解inlining 的里里外外
auto_ptr源代码请参考:<More Effective C++> 附录:auto_ptr源代码
简化代码
template<class T>
class auto_ptr
{
public:
// 构造函数,参数带有默认值,
// 可做默认构造函数使用
auto_ptr(T* p = NULL)
: pointee(p)
{
}
// 重载的构造函数,
// 即使传入对象包含的指针所指对象类型不一致也可
template<class U>
auto_ptr(auto_ptr<U>& rhs)
: pointee(rhs.release())
{
}
// 析构函数, 如果pointee不为空,才调用delete operator
~auto_ptr()
{
if (pointee != NULL)
delete pointee;
}
// 赋值操作,需小心自赋值问题
template<class U>
auto_ptr<T>& operator = (auto_ptr<U>& rhs)
{
if (this != &rhs)
reset(rho.release());
return *this;
}
// 解引用操作符
T& operator*() const
{
return *pointee;
}
// 成员访问操作符
T* operator->() const
{
return pointee;
}
// 获取所包含的对象指针
T* get() const
{
return pointee;
}
// 释放包函数的对象指针
T* release()
{
T* oldPointer = pointee;
pointee = NULL;
return oldPointer;
}
// 重置所包含的对象指针
void reset(T* p = NULL)
{
if (pointee != NULL)
delete pointee;
pointee = p;
}
private:
// 唯一的成员变量,对象指针
T* pointee;
}