栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++系列学习

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++系列学习

[C++11] std::unique_ptr详解

std::unique_ptr是C++11引入的智能指针。C++11引入了move语义,可以转移对象的所有权。

1. unique_ptr介绍
  • unique_ptr不共享其指针。它不能复制到另一个unique_ptr,无法通过值传递到函数,也无法用于需要副本的任何标准模板库算法。只能移动unique_ptr。这意味着,内存资源所有权将转移到另一unique_ptr,并且原始unique_ptr不再拥有此资源。当需要智能指针拥有纯C++对象时,可使用unique_ptr,而当构造unique_ptr时,可使用make_unique函数。
  • 下图演示了两个unique_ptr实例之间的所有权转换:
2. 创建unique_ptr
  • unique_ptr与shared_ptr不同,没有类似make_shared的标准库函数返回一个unique_ptr。要创建一个unique_ptr,需要将其绑定到一个new返回的指针上。

  • std::make_unique是C++14才有的特性

    unique_ptr p1; //可以指向一个double的unique_ptr
    unique_ptr p2(new int(42));	//p2指向一个值为42的int
    
  • 由于一个unique_ptr拥有它指向的对象,因此unique_ptr不支持普通的拷贝或赋值操作

    unique_ptr p1(new string("hello");
    unique_ptr p2(p1);	//错误:unique_ptr不支持拷贝
    unique_ptr p3;
    p3 = p1;					//错误:unique_ptr不支持赋值
    
  • unique_ptr可以进行移动构造和移动赋值操作。如果需要转移所有权,可以使用std::move()函数

    unique_ptr p1(new int(5));
    unique_ptr p2 = std::move(p1);	//转移所有权
    unique_ptr p3(std::move(p2);	//移动构造,转移所有权
    
3. 传递unique_ptr和返回unique_ptr
  • 不能拷贝unique_ptr的规则有一个例外:可以拷贝或赋值一个将要被销毁的unique_ptr。此时,执行一种特殊的拷贝(移动拷贝)

    #最常见的例子是从函数返回一个unique_ptr。
    unique_ptr clone(int p)
    {
    	return unique_ptr(new int(p));	//正确:从int*创建一个unique_ptr
    }
    
    #还可以返回一个局部对象的拷贝
    unique_ptr clone(int p)
    {
    	unique_ptr ret(new int(p));
    	//……
    	return ret;
    }
    
4. unique_ptr操作
	```
	unique_ptr u1;		// 空unique_ptr,可以指向类型为T的对象。u1会使用delete来释放它的指针。
	unique_ptr u2;	// u2会使用一个类型为D的可调用对象来释放它的指针
	unique_ptr u(d);	// 空unique_ptr,指向类型为T的对象,用类型为D的对象d代替delete;
	u = nulptr;				// 释放u指向的对象,将u置为空
	u.release();			// u放弃对指针的控制权,返回指针,并将u置为空
	u.reset();				// 释放u指向的对象
	u.reset(q);				// 如果提供了内置指针q,令u指向这个对象;否则将u置为空
	u.reset(nullptr);
	```
5. unique_ptr使用场景
  1. **为动态申请的资源提供异常安全保证:**当动态申请内存后,可能会由于抛出异常或提前退出而没有指向delete操作,解决办法是使用unique_ptr来管理动态内存,只有unique_ptr指针创建成功,其析构函数都会被调用,确保动态资源被释放。

  2. 返回函数内动态申请资源的所有权

  3. 在容器中保存指针:

    std::vector> vec;
    unique_ptr p(new int(5));
    vec.push_back(std::move(p));		//使用移动语义
    
  4. 管理动态数组

  5. 作为auto_ptr的替代

6. 总结
  1. unique_ptr独占对象,只有移动语义
  2. unique_ptr可以不占有对象,即为空。可以通过nullptr或reset()释放管理对象
  3. 标准库早期版本定义了auto_ptr,它具有unique_ptr的部分特征,但不是全部。例如不能在容器中保存auto_ptr,不能从函数中返回auto_ptr等,这也是unique_ptr主要的使用场景
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/847831.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号