C++ 中 unique_ptr 的声明和使用
指针在 C++ 中有许多有用的用途。 从节省程序空间到帮助实现数据结构,指针对于 C 和 C++ 等编程语言来说是非常重要的工具。
本文将讨论这样一种指针的概念,即唯一指针。 C++标准库提供了该指针作为智能指针的实现之一。
想知道这些智能指针现在是什么? 继续阅读; 我们为您准备好了一切。
C++ 中 unique_ptr 的声明和使用
我们已经知道指针用于存储其他变量的地址。 尽管这些指针在很多地方都很有用,但它们有一个主要问题。
查看给定的代码块。 大多数时候,我们如下声明一个指针,然后使用它,但永远不会删除它。
void demo(){
int *d = new int;
*d = 10;
}
这会导致内存泄漏的问题。 当内存部分在使用后未释放或释放时,就会发生这种情况。
因此,既不可供任何其他程序使用也不空闲的内存会导致空间浪费并降低性能。 这只不过是内存泄漏。
当程序比较复杂时,这甚至可能导致整个堆内存变得无用。 于是,C++11提出了智能指针的概念来解决这个问题。
C++ 中的智能指针
Java 和 C# 等语言有一种机制,可以自动释放未使用的内存。 因此,程序员不需要释放指针,垃圾收集系统将负责处理。
对于 C++,这是通过使用智能指针来实现的。 智能指针只不过是包装原始指针和重载运算符(例如 * 和 ->)的简单类。
智能指针类的对象看起来与普通指针相同,但与普通指针不同的是,它们本身可以释放未使用的内存空间。 C++ 标准库的
现在,我们准备开始学习 C++ 的独特指针。
C++ 中的独特指针
开发了一个unique_ptr来替代C++的auto_ptr。 与原始指针不同,unique_ptr 是原始指针的容器,保证独占所有权且无内存泄漏。
C++ 中 unique_ptr 的声明
下面的代码展示了我们如何在 C++ 中声明一个唯一的指针。
std::unique_ptr<Type> p(new Type);
在这里,如果我们想创建一个指向整数(例如 10)的唯一指针,那么上面的语法将发生变化。
std::unique_ptr<int> p(new int(10));
上面这行代码表示一个唯一的指针p,指向值10。您必须了解这个基本声明是如何工作的。
新表达式在上面的代码行中创建指针 p。 但是,如果我们将相同的声明更改为下面给出的声明,则含义会发生变化。
std::unique_ptr<int> p2(x);
现在,指针被存储在变量 x 中。 从概念上讲,事情是一样的。
我们在两个地方都创建了 unique_ptr,但不建议使用第二种方法。
使用第二种方法,我们可以这样做:
std::unique_ptr<int> p2(x);
std::unique_ptr<int> p3(x);
//....
std::unique_ptr<int> p6(x);
这意味着多个唯一指针拥有同一个对象,这违反了唯一指针的语义,正如您将在以下各节中看到的那样。
另外,在 C++14 中,我们可以选择使用 make_unique 来声明 unique_ptr,如下所示:
unique_ptr<int> d = make_unique<int>(10);
这将创建一个指向值 10 的唯一指针 d。
现在让我们一一看看unique_ptr的各种特性。
自动删除 C++ unique_ptr
对于原始指针,程序员经常忘记在使用后删除指针,从而导致内存泄漏问题。 unique_ptr 避免了这个麻烦,因为当 unique_ptr 超出范围时,它会销毁它所保存的对象。
当unique_ptr被销毁,或者另一个指针被分配给unique_ptr时,该对象也被销毁。 这是在 get_deleter() (ptr) 的帮助下完成的,它使用删除运算符来销毁对象并释放内存。
因此,当您使用 unique_ptr 时,不必删除动态分配的对象,unique_ptr 的析构函数将处理该问题。
下面的代码显示了指针被销毁的范围。
void demo()
{
unique_ptr<int> demo (new int);
} <------------------------- scope of the pointer ends here
当控件超出这些花括号时,该对象将被销毁。
C++ unique_ptr 的独占所有权
unique_ptr 的下一个也是非常重要的功能提供了对象的独占所有权并且无法复制。 这意味着只有一个 unique_ptr 只能同时指向一个对象。
这也是我们无法复制 unique_ptr 的原因。 通常,对于原始指针,正常赋值会导致复制指针。
但 unique_ptr 的情况并非如此。 看这个例子。
这里,我们有两个唯一的指针,p1 和 p2,我们将第一个指针复制或分配给第二个指针。
#include<iostream>
#include<memory>
using namespace std;
int main()
{
unique_ptr<int> p1 (new int);
unique_ptr<int> p2 = p1;
cout << "Success";
return 0;
}
输出:
use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]'
8 | unique_ptr<int> p2 = p1;
你可以看到我们得到了一个编译时错误,并且打印语句没有被执行。 这清楚地表明我们无法在 C++ 中复制 unique_ptr,它同时仅指向一个对象。
现在,如果我们使用原始指针来完成此操作,则打印语句将成功执行。 这是在下面完成的。
#include<iostream>
using namespace std;
int main()
{
int *ptr1;
int *ptr2;
ptr2=ptr1;
cout << "Success";
return 0;
}
输出:
Success
这次指针被复制,因为它们是原始指针。 这本质上就是 unique_ptr 在复制方面的工作原理。
C++ unique_ptr 所有权的转移
如前所述,我们不能通过简单地复制 unique_ptr 来更改它们的所有权。 这里的解决方案是使用C++标准库提供的 move()
函数。
我们使用与尝试使用赋值运算符复制 unique_ptr 相同的代码。 然而,这一次,我们将在分配过程中使用 move()
函数。
#include<iostream>
#include<memory>
using namespace std;
int main()
{
unique_ptr<int> p1 (new int);
unique_ptr<int> p2 = move(p1); //using the move() function
cout << "Success";
return 0;
}
输出:
Success
现在,由于我们使用了 move()
函数,因此不会收到任何错误,并且 print 语句也会执行。
这就是我们如何将一个对象的所有权转移到另一个 unique_ptr,但在任何情况下,unique_ptr 指向的对象一次仍然是一个。
这些是 unique_ptr 与原始指针不同的主要特征。
总结
在本文中,我们了解了 C++ 中唯一指针的概念。 独特指针是一种以其独占所有权和自动删除功能而闻名的智能指针。
我们了解了它是如何声明的,以及如何使用 move()
函数仍然转移唯一指针的所有权。 现在您了解了它们的功能,希望您能够在需要时使用独特的指针。
相关文章
C++ 中的悬空指针
发布时间:2023/08/20 浏览次数:200 分类:C++
-
本文将讨论什么是悬空指针。C++ 中的悬空指针 悬空指针是指向不再存在的对象的指针(引用)。 当对象被删除时,指针指向它原来所在的内存地址。
在 C++ 中 using 与 typedef
发布时间:2023/08/20 浏览次数:138 分类:C++
-
本文试图区分 typedef 和 using。 在 C++ 函数式编程中,这些关键字具有相同的目的和语义,它们之间的差异非常小。本文将解释不同上下文中的关键字,以确保读者理解这些关键字的作用以及 t
C++ 中函数指针的 Typedef
发布时间:2023/08/20 浏览次数:54 分类:C++
-
本文将解释 C/C++ 中 typedef 的用途。 我们将进一步讨论如何将 typedef 与函数指针一起使用以及使用它的好处是什么。我们首先讨论 typedef 及其常见用途。typedef 关键字
使用 C++ 检测 Windows 中的按键
发布时间:2023/08/19 浏览次数:127 分类:C++
-
本文将讨论如何使用 C++ 处理 Windows 应用程序中的按键。 在进一步讨论之前,我们将简要介绍一下使用 C++ 的 Windows 应用程序。使用 C++ 的 Windows 应用程序类型
使用 C++ 在 While 循环中输入字符
发布时间:2023/08/19 浏览次数:62 分类:C++
-
这个简单的文章将讨论在 C++ 中处理输入。 此外,我们将研究处理用户无效输入的问题。 最后,我们将讨论如何使用 while 循环从用户处获取输入。
C++ 中的 STL 容器中的 value_type
发布时间:2023/08/19 浏览次数:115 分类:C++
-
STL 是标准模板库的缩写。 它是一组数据结构和算法,用于实现 C++ 编程语言的通用容器和函数。在 C++ 中,容器将数据存储在特定类型的对象中。 有两种容器:序列容器(按顺序保存对象)和
C++ 中的常量参数
发布时间:2023/08/19 浏览次数:96 分类:C++
-
const 关键字在 C++ 中用于将变量定义为常量。 该关键字可以应用于任何数据类型,但最常应用于指针和引用。常量参数是可以由同一范围内的任何函数设置和使用的值。 该参数应在使用该参数
在 C++ 中创建表
发布时间:2023/08/19 浏览次数:68 分类:C++
-
在C++中,可以使用 iomanip 库以表格的形式显示数据。 我们还将了解 iomanip 库有助于打印表中数据的各种方法。在本文中,我们将讨论如何在 C++ 中以表格的形式打印数据。
C++ 中的 POD 类型
发布时间:2023/08/19 浏览次数:188 分类:C++
-
C++ 中的 POD 代表普通旧数据。 它是一个用关键字 struct 或 class 定义的类,只有 int、char、double、bool、signed/unsigned、long/short、float 等数据成员。C++ 中的 POD 类型