刚接触智能指针,先写下来以免忘记,可能会有解释不正确的地方
using namespace std;
#include<iostream>
//智能指针都是栈上的对象
template<class T>
class Autoptr
{ //初始化创建一个变量赋予一个初始值
public:
Autoptr(T* ptr = NULL) //构造函数-获取资源并初始化,获取对象的所有权,构造函数与类同名,没有返回类型
:_ptr(ptr) //:冒号起是分割作用,类给成员变量赋值的方法,初始化列表,各初始化变量之间以逗号隔开,列表初始化
{}
Autoptr(Autoptr<T>& ap) //拷贝构造,类X的拷贝构造函数的形式为X(X& Y),显示调用,否则系统默认生成拷贝构造函数(浅拷贝)
{
_ptr = ap._ptr; //等同于函数体外:_ptr(ap._ptr)
ap._ptr = NULL; //拷贝构造函数进行深拷贝,重新分配内存
}
Autoptr<T>& operator=(Autoptr<T>& ap) //运算符重载 ,拷贝构造函数功能与赋值函数功能相同,模板+指针运算符重载构成智能指针
{
if (this != &ap)
{
delete _ptr; //将_ptr所指的空间释放掉,将ap._ptr所指的内容拷贝到_ptr
_ptr = ap._ptr; //ap._ptr
ap._ptr = NULL;
}
return *this; //如果是自己给自己赋值返回*this
}
T* operator->() //重载 ->指针运算符
{
return _ptr; //使用智能指针和普通指针一样使用时,要重载运算符,将原始指针进行返回
}
T operator*() //重载* 解引用运算符
{
return *_ptr;
}
~Autoptr() //析构函数-释放资源
{
delete _ptr;
_ptr = NULL;
}
void Reset(T* ptr=0) //重置Auto_ptr对象,如不重置,则传递0值,
{
if (_ptr != ptr)
{ //指针_ptr不为NULL,调用delete操作符系统自动调用析构函数了
delete _ptr; //重置之前被删除,指针_ptr已经是NULL,调用delete操作符系统不会再调用析构函数了
} //释放原来指向的那块动态分配的空间
_ptr = ptr;
}
public:
T* _ptr; //指针,指向动态分配的内存
};
int main()
{
Autoptr<int> ap1(new int(10)); //临时对象,又为右值
cout << "*ap1 = " << *ap1 << endl;
Autoptr<int> ap2(ap1); //ap2夺取ap1的管理权,导致ap1被置为NULL,访问它时程序会崩溃
cout << "*ap2 = " << *ap2 << endl;
Autoptr<int> ap3(new int(20));
ap3 = ap2; //智能指针只能在栈上建立,这样智能指针一定可以被释放,那么普通指针就可以不用管释放的问题了,统一由智能指针帮忙释放,实质上智能指针将普通指针包起来
cout << "*ap3 = " << *ap3 << endl;
ap1.Reset(ap3._ptr);
cout << *ap1 << endl;//报错
system("pause"); //完全的权限转移导致拷贝构造之后只有一个指针可用,其他指针置为Null,使用不方便,解引用时会导致程序崩溃
//模板+运算符重载构成智能指针
return 0;
}