前面我们讲解了auto_ptr的使用及为什么会被C++11标准抛弃,接下来,我们来学习auto_ptr的升级版本unique_ptr
的使用:
C++新特性20_unique_ptr的使用
1. unique_ptr提供的接口:
看起来似乎与auto_ptr相似,但是其实有区别。
1.1 构造函数与=运算符重载的禁止
虽然这里的构造函数比较多,但是可以发现,实际上是没有类似auto_ptr的那种拷贝构造和=运算符重载,这是因为auto_ptr对其禁止:
void foo_constuct()
{
//这样构造是可以的
std::unique_ptr<int> p(new int(3));
//空构造
std::unique_ptr<int> p4;
//下面三种写法均禁止,会报错
std::unique_ptr<int> p2 = p; //需要拷贝构造
std::unique_ptr<int> p3(p); //需要拷贝构造
p4 = p; //需要=运算符重载
}
因此,这就从根源上杜绝了auto_ptr作为参数传递的写法了。
1.2 reset()
reset的用法和auto_ptr是一致的:
代码:
void foo_reset()
{
//释放
int* pNew = new int(3);
int*p = new int(5);
{
std::unique_ptr<int> uptr(pNew);
uptr.reset(p);
}
}
reset之前:
reset之后:
1.3 release()
release与reset一样,也不会释放原来的内部指针,只是简单的将自身置空。
void foo_release()
{
//释放
int* pNew = new int(3);
int* p = NULL;
{
std::unique_ptr<int> uptr(pNew);
p = uptr.release();
}
}
1.4 move()
move()的出现相对于auto_ptr更进一步。
auto_ptr中的赋值操作可以看做默认的一个剪贴操作,在unique_ptr中将剪贴操作看做一个利用move将其显化的操作,虽然与auto_ptr起到的作用相同,但是因为显化了,更好用(但是还是一样啊,苦笑脸!)。
因为unique_ptr不能将自身对象内部指针直接赋值给其他unique_ptr,所以这里可以使用std::move()函数,让unique_ptr交出其内部指针的所有权,而自身置空,内部指针不会释放。
1.5 数组
可以采用move的方法来使用数组。
直接使用仍然会报错,但是使用move就可以了(实际操作还是会报错!):
void foo_ary()
{
std::vector<std::unique_ptr<int>> Ary;
std::unique_ptr<int> p(new int(3));
//明确将值剪切给参数
Ary.push_back(std::move(p));
//到此步,p的值为empty,报错
printf("%d\r\n", *p);
}
所以综上,unique_ptr指的是只有一个对象拥有指针的所有权,可以转移,但是不能直接赋值或者拷贝构造。
move()的使用使得可以完成一个剪切操作,但剪切完之后依然是不能调用的,还是比较恶心,后边将会使用引用计数版本的智能指针,用法更为舒适。
2.学习视频:unique_ptr的使用
3.学习笔记:unique_ptr的使用学习笔记