C++之智能指针(二)
auto_ptr指针
通过模拟实现auto_ptr的功能来认识auto_ptr智能指针
auto_ptr的特点:
- 不允许隐式构造
- 不能将同一个裸指针赋值给多个智能指针
- 允许普通的拷贝构造和等号运算符重载
- 允许对即将死亡的对象做拷贝构造和等号运算符重载 消除资源直接使用delete
template<typename T>
class Mauto_ptr
{
public:
//不允许隐式构造
explicit Mauto_ptr(T* ptr = NULL)//explicit可禁止隐式构造
{
_ptr = ptr;
}
Mauto_ptr(const Mauto_ptr& src)//拷贝构造
{
if (&src == this)//防止自拷贝
{
return;
}
_ptr = src._ptr;
src._ptr = NULL;
//这是auto_ptr拷贝构造的最大特点,新的智能指针=拷贝构造成功之后,会将原智能指针置空
}
Mauto_ptr& operator=(const Mauto_ptr& src)
{
if (this == &src)//防止自赋值
{
return *this;
}
_ptr = src._ptr;
src._ptr = NULL;//和拷贝构造一样,赋值完成之后,会将原智能指针置空
return *this;
}
~Mauto_ptr()//auto_ptr的析构直接调用delete就行
{
delete _ptr;
}
T* get()//获取内部指针,这里的内部指针也就是智能构造之前的裸指针
{
return _ptr;
}
T* release()//将智能指针清空,并返回该智能指针
{
T* tmp = _ptr;
_ptr = NULL;//注意:这里的只是把智能指针置空,裸指针还在
return tmp;
}
void reset()//将内部指针释放,之后再将智能指针清空
{
delete _ptr;//注意:这里是直接将裸指针给析构掉了,这是裸指针也会消失
//始终切记一点:智能指针是为了能让原本的裸指针不在手动进行delete,所以析构智能指针其实就是delete裸指针
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
private:
T* _ptr;
};
int main()
{
//把裸指针传到智能指针里边进行构造了之后,
//就不用再手动进行释放了,在智能指针析构的时候,会自动进行释放
int* p = new int(10);
Mauto_ptr<int> a_pl = p;//不允许隐式构造
//隐式构造:编译器通过自推,根据推导出的类型来构造
//显示构造:直接给出一个类型名去构造
Mauto_ptr<int>a_p1(p);
//智能指针其实就是对裸指针的一个封装,先定义一个普通指针,用裸指针去构造一个智能指针
Mauto_ptr<int>a_p3(p);
//不能将同一个裸指针赋值给多个智能指针
//这里后构造的a_p3,先析构,a_p3把p析构之后,a_p1又去析构,自然会报错
Mauto_ptr<int>a_p2(a_p1);
//a_p2析构时把a_p1给置空了,打印*a_p1就会报错
//这里可以打印*p_a2
//cout << *a_p1 << endl;//错
Mauto_ptr<int>a_p4;
a_p4 = a_p1;
//当进行拷贝构造或者等号运算符时候会将源指针中保存的指针置空
cout << p << endl;
cout << a_p1.get() << endl;//获取内部指针
cout << a_p1.release() << endl;//将智能指针清空,并返回该智能指针
cout << *p << endl;
//a_p1.reset();//将内部指针释放,之后再将智能指针清空
//cout << *p << endl;
//cout << *a_p1 << endl;
return 0;
}