C++笔记之unique_ptr转移堆内空间的所有权

2023-10-30 09:30

本文主要是介绍C++笔记之unique_ptr转移堆内空间的所有权,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

C++笔记之unique_ptr转移堆内空间的所有权

code review!

文章目录

  • C++笔记之unique_ptr转移堆内空间的所有权
    • 一.C++笔记之unique_ptr转移堆内空间的所有权
      • 方法1.使用std::move函数
      • 方法2.使用std::unique_ptr的reset方法
      • 方法3.返回unique_ptr
      • 方法4.std::unique_ptr的swap方法
    • 二.unique_ptr的reset和release方法
      • 1.调用无参数的reset()方法
      • 2.调用有参数的reset()方法
    • 三.面试问题:返回局部变量的std::unique_ptr可以转移堆内存的所有权吗?
    • 四.通过 `std::move` 将所有权转移到调用函数中的另一个 `std::unique_ptr`,解决面试三的问题

一.C++笔记之unique_ptr转移堆内空间的所有权

std::unique_ptr在C++中用于表示对堆内存的独占所有权。这是一种非常有用的工具,可以帮助避免内存泄漏,并使内存管理变得更为简单。关于std::unique_ptr所有权的转移,主要有以下几种方式:

方法1.使用std::move函数

例1
在这里插入图片描述

例2
在这里插入图片描述

方法2.使用std::unique_ptr的reset方法

你可以使用reset方法将一个新的原始指针赋给unique_ptr。这将导致unique_ptr放弃对其当前内存的所有权,并接管新内存的所有权。
例1
在这里插入图片描述

例2
在这里插入图片描述

方法3.返回unique_ptr

在函数中,你可以返回一个unique_ptr,从而将所有权传递给调用者。例如:
在这里插入图片描述

方法4.std::unique_ptr的swap方法

通过std::unique_ptr的swap方法:可以交换两个unique_ptr的所有权。
在这里插入图片描述

以上就是unique_ptr所有权转移的几种主要方式。请注意,因为unique_ptr代表的是独占所有权,所以你不能通过赋值或复制将一个unique_ptr的所有权给另一个unique_ptr。尝试这样做会导致编译错误。

二.unique_ptr的reset和release方法

在这里插入图片描述

1.调用无参数的reset()方法

在这里插入图片描述

2.调用有参数的reset()方法

在这里插入图片描述

三.面试问题:返回局部变量的std::unique_ptr可以转移堆内存的所有权吗?

不可以。返回指向局部变量的 std::unique_ptr 并不能转移堆内存的所有权,因为局部变量的生命周期在函数退出时结束,此时 std::unique_ptr 的析构函数会被调用,尝试释放已经无效的内存地址,可能会导致未定义行为。

std::unique_ptr 的核心特性是独占所有权,它确保在一个时间点只有一个 std::unique_ptr 指向一个特定的资源。如果你希望将堆内存的所有权转移给另一个 std::unique_ptr,你应该使用 std::move 函数来显式地转移所有权。

下面是一个例子,演示了在函数中返回 std::unique_ptr 的情况:

#include <iostream>
#include <memory>std::unique_ptr<int> createUniquePtr(int value) {std::unique_ptr<int> ptr(new int(value));return ptr; // 返回局部变量,尝试转移所有权,但是会导致问题
}int main() {std::unique_ptr<int> ptr = createUniquePtr(42); // 错误:悬空指针,因为局部变量已经被销毁// 尝试访问 ptr 会导致未定义行为return 0;
}

上述代码会产生未定义行为,因为在 createUniquePtr 函数退出时,局部变量 ptr 将被销毁,std::unique_ptr 的析构函数将被调用,尝试释放已经无效的内存。

要避免这种情况,你应该在函数中创建一个 std::unique_ptr,然后通过 std::move 将所有权转移到调用函数中的另一个 std::unique_ptr

四.通过 std::move 将所有权转移到调用函数中的另一个 std::unique_ptr,解决面试三的问题

在这里插入图片描述
std::move 是一个 C++ 标准库中的函数,它将一个左值(左值引用)转换为右值引用,从而允许将资源的所有权有效地从一个对象转移到另一个对象,而不触发资源的拷贝或移动操作。

在上述例子中,std::move(ptr)std::unique_ptr<int> 对象 ptr 从一个左值转换为一个右值引用,使得 createUniquePtr 函数可以接受并返回这个右值引用,从而实现了资源的所有权转移。

这样做的好处是,可以避免不必要的资源拷贝和移动,从而提高代码的效率。但要注意,一旦资源的所有权转移后,原始的对象(在这里是 ptr)应该被视为无效,不再访问或使用它,以防止悬空指针和未定义行为。

这篇关于C++笔记之unique_ptr转移堆内空间的所有权的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/306964

相关文章

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

C++作用域和标识符查找规则详解

《C++作用域和标识符查找规则详解》在C++中,作用域(Scope)和标识符查找(IdentifierLookup)是理解代码行为的重要概念,本文将详细介绍这些规则,并通过实例来说明它们的工作原理,需... 目录作用域标识符查找规则1. 普通查找(Ordinary Lookup)2. 限定查找(Qualif

C/C++ chrono简单使用场景示例详解

《C/C++chrono简单使用场景示例详解》:本文主要介绍C/C++chrono简单使用场景示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录chrono使用场景举例1 输出格式化字符串chrono使用场景China编程举例1 输出格式化字符串示

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以

C++类和对象之默认成员函数的使用解读

《C++类和对象之默认成员函数的使用解读》:本文主要介绍C++类和对象之默认成员函数的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、默认成员函数有哪些二、各默认成员函数详解默认构造函数析构函数拷贝构造函数拷贝赋值运算符三、默认成员函数的注意事项总结一