智能指针是模板类,定义该类的对象变量存放在栈中,智能指针负责管理 指向堆内存的指针变量。众所周知,堆内存的创建与释放需要new/delete操作,这样会出现忘记delete堆内存的情况,从而造成内存泄漏。为此,智能指针就出现了。
原理:智能指针是类,该类创建的对象在栈空间,栈中的变量是局部变量,不用程序员管理,在程序退出作用域后相应的变量被释放,表现为栈顶指针的变化。前面讲过,智能指针负责管理指向堆内存的指针变量,这里,在析构智能指针时,顺便释放堆内存,不就可以很好的避免内存泄漏的问题了。
智能指针所在的头文件 #include<memory>
这里先介绍两种智能指针 auto_ptr,unique_ptr
1、auto_ptr
(1)创建
int * a = new int(12);
auto_ptr<int> p1(a);
auto_ptr<int> a1;
a1.reset(new int(5));
auto_ptr<int> a2(a1); //拷贝构造
auto_ptr<int> a3 = a1; //拷贝构造
(2)赋值
a2 = a1;
(3)管理权限转移
首先,以上的拷贝构造与赋值都会转移管理权限,将被拷贝对象的管理对象交由待拷贝,或赋值等号右边的管理对象交由左边的智能指针,且在转移管理权限后,智能指针管理的堆内存的指针被置为NULL
另一种转移方式是
auto_ptr<int> a4 = move(a2);
将a2的管理对象交由a4管理,且在转移管理权限后,智能指针a2管理的堆内存的指针被置为NULL
2、unique_ptr
(1)创建
int * b = new int(12);
unique_ptr<int> pp1(b);
unique_ptr<int> pp2;
pp2.reset(new int(5));
不支持拷贝构造
(2)赋值
不支持
(3)管理权限转移
unique_ptr<int> pp3 = move(pp1);
将pp1的管理对象交由pp3管理,且在转移管理权限后,智能指针pp1管理的堆内存的指针被置为NULL
两者区别:显然,auto_ptr支持拷贝构造与赋值,而unique_ptr不支持,这样,使用unique_ptr的程序不会等到运行阶段崩溃,而在编译期出现错误,避免潜在的错误。