继auto_ptr智能指针之后,在c++11中又提供了三种智能指针,分别是unique_ptr,shared_ptr和weak_ptr。auto_ptr在上一篇文章中以及详细介绍过了,接下来我们就来了解一下其他的几种智能指针。
通过上一篇文章的学习(auto_ptr详解),我们知道auto_ptr在赋值之后会产生悬挂指针,稍不注意就会因为访问悬挂指针而导致程序奔溃。为了避免潜在的内存问题,c++11已经摒弃了auto_ptr,并且推出了unique_ptr来替代auto_ptr。
1.避免unique指针之间的赋值操作
unique_ptr指针取消了赋值操作,避免像auto_ptr那样产生悬挂指针而导致潜在的内存问题。unique_ptr是持有对象所有权的,正如它的名字一样,是唯一的,即两个unique_ptr不能指向同一个对象。并且不能进行赋值操作只能使用move来转移所有权。
unique_ptr<int> ptr1(new int(10));
unique_ptr<int> ptr2 = ptr1; //error 不支持赋值操作
unique_ptr<int> ptr3(ptr1);//error unique_ptr没有拷贝构造函数
unique_ptr相比于auto_ptr的好处就是在编译阶段就禁止了类似的赋值操作,避免产生难以发觉的安全隐患。
unique_ptr<int> ptr2 = unique_ptr<int> (new int(10));
3.使用move函数转移所有权
前面说到unqiue_ptr不能够有任何的赋值行为,但是可以通过c++标准库的move函数来实现所有权转移,原来的指针会变成空指针,可以对其重新赋值,所以在重新赋值前请不要访问原来的指针,避免造成访问空指针的错误,如下:
unique_ptr<int> ptr1 = unique_ptr<int> (new int(10));
cout << *ptr1 << endl;
unique_ptr<int> ptr2 = move(ptr1);
cout << *ptr2 << endl;
cout << *ptr1 << endl;//error 访问空指针
1.reset函数
reset函数作用是将unique_ptr指针置空,如下:
#include
#include
using namespace std;
int main()
{
unique_ptr<int> ptr1 = unique_ptr<int> (new int(10));
cout << *ptr1 << endl;
ptr1.reset();
if(ptr1==nullptr)
{
cout << "ptr1 is nullptr "<< endl;
}
return 0;
}
运行结果如下:
从运行结果可以看出调用reset方法之后,ptr1就是一个空指针了。
2.swap函数
该函数作用是交换两个unique_ptr指针所指的对象,如下:
#include
#include
using namespace std;
int main()
{
unique_ptr<int> ptr1 = unique_ptr<int> (new int(10));
cout << *ptr1 << endl;
unique_ptr<int> ptr2 = unique_ptr<int> (new int (20));
cout << *ptr2 << endl;
ptr1.swap(ptr2);//交换ptr1和ptr2的对象
cout << *ptr1 << endl;
cout << *ptr2 << endl;
return 0;
}
运行结果如下:
可见,调用swap函数之后,ptr1和ptr2所指的对象交换了。
3.get函数
get函数也非常简单,调用该函数会返回智能指针对象的地址。
#include
#include
using namespace std;
int main()
{
unique_ptr<int> ptr1 = unique_ptr<int> (new int(10));
unique_ptr<int> ptr2 = unique_ptr<int> (new int (20));
cout << ptr1.get() << endl;
cout << ptr2.get() << endl;
return 0;
}
运行结果如下:
如结果显示,这两个地址就是ptr1和ptr2所指对象的地址。
4.release函数
release函数的作用就是返回对象内存地址并释放所有权。
#include
#include
using namespace std;
int main()
{
unique_ptr<int> ptr1 = unique_ptr<int> (new int(10));
unique_ptr<int> ptr2 ;
cout << ptr1.get() << endl;//打印智能指针对象地址
cout << ptr1.release() << endl;//查看release函数返回值
if(ptr1==nullptr)
{
cout << "ptr1 is null ptr" << endl;
}
//cout << *ptr1 << endl;
return 0;
}