auto_ptr
- auto_ptr这个智能指针在c++11中已经被遗弃,原因如下:在拷贝与赋值操作时,智能指针所管理的对象会发生拥有权转移,如果这个时候程序员去使用已经被转移拥有权的智能指针,不会发生编译错误,却在访问管理的对象时导致程序运行出错。这是一种很危险的行为。因此在c++11中引入了unique_ptr,参见下篇。
- 示例如下:
#include <iostream>
#include <memory>
using namespace std;
int main() {
auto_ptr<int> ptr1(new int(100));
// 一个赋值操作导致ptr1失去了堆对象的拥有权(钥匙掉了开不了门)
// auto_ptr<int> ptr2 = ptr1;
// cout << *ptr1.get() << endl; // 指针的值为0,访问对象不可行
// 同理,拷贝操作也是
auto_ptr<int> ptr2(ptr1);
cout << *ptr1.get() << endl; // 指针的值为0,访问对象不可行
return 0;
}
- auto_ptr源码如下:
#include <cassert> // for assert
template<typename _Tp1>
struct auto_ptr_ref
{
//内部指针
_Tp1* _M_ptr;
//有参构造函数
explicit auto_ptr_ref(_Tp1* __p) : _M_ptr(__p) { }
};
template<typename _Tp>
class auto_ptr
{
private:
_Tp* _M_ptr;
public:
//指针的类型
typedef _Tp element_type;
explicit auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { }
// 拷贝构造发生所有权转移
auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { }
//模板成员函数(泛型方法),_Tp1类型的指针必须能够转化为_Tp类型的指针
template<typename _Tp1>
auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { }
// 拷贝赋值运算符发生所有权转移
auto_ptr& operator=(auto_ptr& __a) throw()
{
reset(__a.release());
return *this;
}
//模板成员函数,_Tp1类型的指针必须能够转化为_Tp类型的指针
template<typename _Tp1>
auto_ptr& operator=(auto_ptr<_Tp1>& __a) throw()
{
reset(__a.release());
return *this;
}
~auto_ptr() { if (_M_ptr) delete _M_ptr; }
//解除引用
element_type& operator*() const throw()
{
//如果内部指针为空,则中止程序运行
assert(_M_ptr != nullptr);
return *_M_ptr;
}
//解除引用
element_type* operator->() const throw()
{
assert(_M_ptr != nullptr);
return _M_ptr;
}
//获取原始指针资源
element_type* get() const throw() { return _M_ptr; }
//核心:将auto_ptr管理的对象所有权转移
element_type* release() throw()
{
element_type* __tmp = _M_ptr;
_M_ptr = nullptr;
return __tmp;
}
//核心:强制重置_M_ptr,析构资源,将_p赋值给_M_ptr
void reset(element_type* __p = 0) throw()
{
if (__p != _M_ptr)
{
delete _M_ptr;
_M_ptr = __p;
}
}
//自动转化
auto_ptr(auto_ptr_ref<element_type> __ref) throw()
: _M_ptr(__ref._M_ptr) { }
//将__ref的所有权转让给_M_ptr
auto_ptr& operator=(auto_ptr_ref<element_type> __ref) throw()
{
if (__ref._M_ptr != this->get())
{
delete _M_ptr;
_M_ptr = __ref._M_ptr;
}
return *this;
}
//类型转化函数
template<typename _Tp1>
operator auto_ptr_ref<_Tp1>() throw()
{
return auto_ptr_ref<_Tp1>(this->release());
}
//类型转换函数,将_Tp类型的指针对象_M_ptr转化为auto_ptr<_Tp1>
template<typename _Tp1>
operator auto_ptr<_Tp1>() throw()
{
return auto_ptr<_Tp1>(this->release());
}
};
//模板特化版本
template<>
class auto_ptr<void>
{
public:
typedef void element_type;
};