C++11智能指针中的 unique_ptr实例详解

C++11智能指针中的 unique_ptr实例详解

简介

在C++11中,引入了新的智能指针模板类unique_ptr,它能自动管理动态内存,从而避免内存泄漏和野指针等问题。unique_ptr是一个独占式智能指针,它禁止拷贝和赋值,并在生命周期结束时自动释放内存。

本篇文章将详细介绍unique_ptr的使用方法和注意事项,并结合实例进行说明。

unique_ptr的使用

创建unique_ptr

使用unique_ptr最基本的操作是通过new关键字来创建动态内存并将其封装到unique_ptr对象中。创建unique_ptr的方法如下:

std::unique_ptr<int> ptr(new int(10));

上述代码中,我们创建了一个名为ptr的unique_ptr对象,它持有一个动态分配的整型变量,并将其初始化为10。

但是,unique_ptr是独占式智能指针,它禁止拷贝和赋值,因此不能像普通指针一样进行赋值操作。例如,下面的代码是错误的:

std::unique_ptr<int> ptr1(new int(10));
std::unique_ptr<int> ptr2 = ptr1;

由于unique_ptr禁止拷贝和赋值,因此上述代码会导致编译错误。

unique_ptr的释放

unique_ptr在生命周期结束时自动释放动态内存,这个过程叫做unique_ptr的“析构”。unique_ptr的析构函数会自动调用delete操作符,从而释放其所持有的动态内存。下面的代码展示了unique_ptr的析构过程:

{
    std::unique_ptr<int> ptr(new int(10));
} // ptr的生命周期结束,指向的动态内存将被自动释放

获取unique_ptr所持有的指针

我们可以通过unique_ptr的get()成员函数来获取unique_ptr所持有的指针。下面的代码展示了如何使用get()函数:

std::unique_ptr<int> ptr(new int(10));
int* p = ptr.get(); // p指向ptr所持有的动态内存

使用unique_ptr作为函数参数

unique_ptr可以作为函数参数传递。由于unique_ptr禁止拷贝和赋值,因此函数参数只能通过引用或移动语义来传递unique_ptr。

下面的代码展示了如何在函数中使用unique_ptr:

void func(std::unique_ptr<int>& ptr) {
    // do some operations with ptr
} // ptr的生命周期结束,指向的动态内存将被自动释放

std::unique_ptr<int> ptr(new int(10));
func(ptr); // 传递unique_ptr的引用

将指针交换给unique_ptr

我们可以使用unique_ptr的swap()成员函数将一个指针交换给unique_ptr,这样可以让unique_ptr接管原指针的所有权。

int* p = new int(10);
std::unique_ptr<int> ptr;
ptr.swap(std::unique_ptr<int>(p)); // 将指针p交换给ptr,ptr现在持有p的所有权

重置unique_ptr

unique_ptr提供了reset()函数用于释放原指针并重新指向新的指针。

std::unique_ptr<int> ptr(new int(10));
ptr.reset(new int(20)); // 释放原指针并指向新的指针

unique_ptr的实例

示例一:在函数中返回unique_ptr

下面的代码展示了如何在函数中使用unique_ptr,通过返回unique_ptr来避免内存泄漏的问题。

// 返回一个unique_ptr,该指针持有一个动态分配的字符串对象
std::unique_ptr<std::string> getString() {
    std::unique_ptr<std::string> ptr(new std::string("hello world"));
    return ptr; // 返回unique_ptr
}

void printString() {
    std::unique_ptr<std::string> str = getString(); // 获取返回的unique_ptr
    std::cout << *str << std::endl;
} // str的生命周期结束,指向的动态内存将被自动释放

int main() {
    printString();
    return 0;
}

上述代码中,getString()函数返回一个unique_ptr,该指针持有一个动态分配的字符串对象。由于返回的是unique_ptr,因此函数结束时该指针会被自动释放,从而避免了内存泄漏的问题。

示例二:使用lambda式创建unique_ptr

下面的代码展示了如何使用lambda式来创建unique_ptr对象。

auto ptr = std::unique_ptr<int>(new int(10));
std::unique_ptr<int> ptr2([=]() {
    auto p = new int(20);
    *p += *ptr;
    return p;
}()); // 使用lambda式创建unique_ptr,该指针持有一个动态分配的整型变量

上述代码中,我们首先使用new关键字创建一个动态分配的整型变量,并将其封装到unique_ptr对象中。然后,我们使用lambda式创建了一个新的unique_ptr对象,它持有另一个动态分配的整型变量,该变量的值为原指针的值加上10。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++11智能指针中的 unique_ptr实例详解 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • ToString()使用方法汇总(c#)

    ToString()使用方法汇总(c#) 什么是ToString() 在C#中,ToString()是一个对象方法,用于将当前对象转换为字符串表示形式。 ToString()的使用 使用ToString()方法可以将对象转换为字符串。ToString()方法有很多重载版本,可以支持不同的数据类型。下面是ToString()方法的一些常见用法: 将数字转换为字…

    C 2023年5月22日
    00
  • C语言中如何实现桶排序

    C语言中实现桶排序,其主要思想是将待排序的序列分解成若干个区间,对于每个区间分别使用一个桶来存放该区间内的元素,然后对每个桶中的元素进行排序,最后按照桶的顺序将所有元素连接起来,就得到了排好序的序列。 具体的实现步骤如下: 1.确定桶的数量和区间范围。根据序列中的元素取值范围,确定桶的数量并计算区间大小。 2.将元素分配到对应的桶中。遍历待排序的序列,将每个…

    C 2023年5月22日
    00
  • C语言基本语法

    当学习 C 语言时,我们需要掌握 C 语言的基本语法,这个攻略将会详细讲解 C 语言的基本语法内容和使用方法。 标识符 C 语言中使用标识符来标识变量、函数等名称。标识符由字母、数字和下划线组成,但第一个字符必须为字母或下划线。标识符大小写敏感。 示例代码: #include <stdio.h> int main() { int a = 10, …

    C 2023年5月9日
    00
  • C语言实现电器销售管理系统

    C语言实现电器销售管理系统攻略 1.设计思路 本系统是一个基于C语言的控制台应用程序,主要实现了电器销售管理的各项功能。在设计时,首先需要确定系统所需要完成的具体功能,包括商品管理、销售管理、统计报表等。然后考虑如何使用C语言实现这些功能。 具体实现方法是:使用结构体来存储商品信息,使用文件来储存数据,通过读写文件实现数据的持久化,使用菜单、输入、输出等操作…

    C 2023年5月30日
    00
  • C++和C的混合编译的项目实践

    下面是关于C++和C的混合编译的项目实践的攻略: 1. 项目背景与说明 在实际项目中,往往存在着C++和C代码混编的需求。比如说,C代码部分用于CPU的中断处理,C++代码部分用于其他系统功能的实现等等。 在实现混合编译的过程中,一定要注意两者的语法规则和编译器的选择问题。 2. 项目实践步骤 2.1 确定混合编译的文件目录结构 project |–inc…

    C 2023年5月23日
    00
  • C/C++ 原生API实现线程池的方法

    C/C++原生API实现线程池,可以通过以下步骤来实现: 第一步:定义线程池结构体 线程池结构体的定义通常包含以下几个成员: 线程池中线程的数量:通过这个成员可以控制线程池中线程的数量 任务队列:用来存储要执行的任务 线程池是否正在运行:通过这个成员可以控制是否继续执行任务 定义如下: typedef struct threadpool { int thre…

    C 2023年5月22日
    00
  • C语言实现简单井字棋游戏

    C语言实现简单井字棋游戏攻略 1. 程序设计思路 为了实现简易版的井字棋游戏,需要经过以下几个步骤: 定义棋盘数组; 实现棋盘的初始化; 实现玩家之间交替下棋; 实现获胜条件的检测; 输出获胜者的信息或平局的信息。 2. 代码实现 2.1. 定义棋盘数组 在C语言中,可以通过二维数组定义棋盘: char board[3][3] = { {‘1’, ‘2’, …

    C 2023年5月23日
    00
  • C语言实现的统计php代码行数功能源码(支持文件夹、多目录)

    以下是C语言实现的统计php代码行数功能源码的完整攻略: 1. 简介 本文介绍如何使用C语言统计PHP代码行数的方法,这个方法是支持多文件夹和多目录的。 主要思路是通过递归遍历文件夹来实现多文件的读取和处理,然后对代码行进行统计。 2. 核心代码实现 2.1. 处理单个文件 我们首先来看如何处理单个文件的代码行数统计。这个过程分为三个步骤: 打开文件,将其读…

    C 2023年5月24日
    00
合作推广
合作推广
分享本页
返回顶部