c++智能指针----unique_ptr

前言

继auto_ptr智能指针之后,在c++11中又提供了三种智能指针,分别是unique_ptr,shared_ptr和weak_ptr。auto_ptr在上一篇文章中以及详细介绍过了,接下来我们就来了解一下其他的几种智能指针。

unique_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的好处就是在编译阶段就禁止了类似的赋值操作,避免产生难以发觉的安全隐患。

  1. 可以使用临时右值赋值
    但是如果在将unique_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 访问空指针

unique_ptr的常用方法

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;	
} 

运行结果如下:
c++智能指针----unique_ptr_第1张图片
从运行结果可以看出调用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;	
} 

运行结果如下:
c++智能指针----unique_ptr_第2张图片
可以很清楚的看到release返回的是智能指针对象的地址,并且释放了对象的所有权,成为了一个空的指针。

你可能感兴趣的:(c++,c++,指针)