unique_ptr使用介绍

1 unique_ptr使用介绍

1.1 unique_ptr的特性

我们先来看下unique_ptr的特性:

  • 基于排他所有权模式:两个指针不能指向同一个资源。
  • 无法进行左值unique_ptr复制构造,也无法进行左值复制赋值操作,但允许临时右值赋值构造和赋值。
  • 保存指向某个对象的指针,当它本身离开作用域时会自动释放它指向的对象。
  • 在容器中保存指针是安全的。

示例代码如下:

#include <stdio.h>
#include <iostream>
#include <string>
#include <memory>
#include <vector>

using namespace std;

int main() {

	//弊端1. auto_ptr 被C++11 抛弃的主要理由 p1= p2 ,复制或赋值都会改变资源的所有权
	//unique_ptr 如何解决这个问题? 不允许显示的右值赋值和构造
	unique_ptr<string> p1(new string("I 'm martin."));
	unique_ptr<string> p2(new string("I 'm rock."));
	printf("p1: %p\n", p1.get());
	printf("p2: %p\n", p2.get());

	//如果一定要转移,使用move 把左值转成右值
	p1 = std::move(p2);
	printf("p1: %p\n", p1.get());
	printf("p2: %p\n", p2.get());

	//p1 = p2;  //左值赋值禁止
	unique_ptr<string> p3(new string("I 'm p3."));
	unique_ptr<string> p4(std::move(p3));  //左值拷贝构造也不行,必须转成右值

	//弊端2. 在 STL 容器中使用auto_ptr存在重大风险,因为容器内的元素必需支持可复制(copy constructable)和可赋值(assignable)。
	vector<unique_ptr<string>> vu;
	unique_ptr<string> p5(new string("I 'm p5."));
	unique_ptr<string> p6(new string("I 'm p6."));

	vu.push_back(std::move(p3));
	vu.push_back(std::move(p4));

	cout << "va[0]: " << *vu[0] << endl;
	cout << "va[1]: " << *vu[1] << endl;

	//vu[0] = vu[1];  //unique_ptr不支持直接赋值,没有风险

	//弊端3. auto_ptr不支持对象数组的内存管理,unique_ptr 支持
//但是unique_ptr 支持对象数组的管理
	//auto_ptr<int[]> ai(new int[5]);  //不能这样定义
	unique_ptr<int[]> ui(new int[5]);  //自动会调用 delete []函数去释放
	system("pause");
	return 0;
}

1.2 unique_ptr常用方法介绍

构造函数:

unique_ptr<T> up ; //空的unique_ptr,可以指向类型为T的对象
unique_ptr<T> up1(new T()) ;//定义unique_ptr,同时指向类型为T的对象
unique_ptr<T[]> up ; //空的unique_ptr,可以指向类型为T[的数组对象
unique_ptr<T[]> up1(new T[]) ;//定义unique_ptr,同时指向类型为T的数组对象
unique_ptr<T,D> up(); //空的unique_ptr,接受一个D类型的删除器d,使用d释放内存(可以不传递)
unique_ptr<T,D> up(new T(), D()); //定义unique_ptr,同时指向类型为T的对象,接受一个D类型的删除器d,使用删除器d来释放内存

赋值:

unique_ptr<int> up1(new int(10));
unique_ptr<int> up2(new int(11));
up1 = std::move(up2);//必须使用移动语义,结果,up1 内存释放, up2 交由up1 管理

主动释放对象:

up = nullptr ;//释放up指向的对象,将up置为空
up = NULL; //作用相同 

放弃对象控制权:

up.release();    //放弃对象的控制权,返回指针,将up置为空,不会释放内存

重置:

up.reset()//参数可以为 空、内置指针,先将up所指对象释放,然后重置up的值交换
up.swap(up1);  //将智能指针up 和up1管控的对象进行交换

参考资料:

  1. C/C++从入门到精通-高级程序员之路【奇牛学院】
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读