智能指针

17 Mar 2025 | 5 分钟阅读

指针用于访问程序外部的资源,例如堆内存。因此,指针用于访问堆内存(如果堆内存中创建了任何内容)。在访问任何外部资源时,我们只是使用它的副本。如果进行任何更改,我们只在复制的版本中进行更改。但是,如果使用指向该资源的指针,我们可以更改原始资源。

普通指针的问题

请查看以下代码。

C++ 代码

函数 fun 生成一个指向 Rectangle 对象的指针。Rectangle 由两个整数组成:length 和 breadth。由于 p 是局部变量,当函数 fun 结束时它将被销毁。但是,由于我们忘记在函数末尾使用 delete p;,它所消耗的内存将不会被释放。这意味着内存将无法供其他资源使用。然而,我们不再需要该变量,而是需要该内存。

Fun 在 main 函数中被无限循环调用。这意味着它将继续生成 p。它将分配更多内存,但不会释放它,因为我们没有释放它。未使用的内存无法再次使用。这导致内存泄漏。因此,整个堆内存可能变得无用。智能指针,C++11 的一个特性,为此问题提供了解决方案。

智能指针简介。

无意识地不释放指针会导致内存泄漏,这可能会导致程序崩溃。Java 和 C# 等语言使用垃圾回收机制来智能地释放未使用的内存,以便可以再次使用。程序员不必担心内存泄漏。智能指针是 C++11 开发的一种机制。当对象被销毁时,内存也会被释放。因此,我们不需要删除它,因为智能指针会处理它。

智能指针是一个指针包装类,它重载了 * 和 -> 等运算符。智能指针类的对象类似于普通指针。但是,与普通指针不同,它能够释放和解除已销毁对象的内存。

考虑一个具有指针、析构函数以及重载运算符(如 * 和 ->)的类。由于当对象超出作用域时析构函数会自动调用,因此动态分配的内存将被删除(或引用计数可以递减)。请考虑下面显示的 SmartPtr 类。

C++ 代码

输出

20

这只适用于 int。那么我们需要为每个对象创建一个智能指针吗?不,模板是一个解决方案。如您在下面的代码中看到的,T 可以是任何类型。单击此处了解有关模板的更多信息。

C++ 代码

输出

20

注意:智能指针还可以用于管理文件句柄或网络套接字等资源。

智能指针类型

1. unique_ptr

unique_ptr 只存储一个指针。通过从指针中移除当前对象,我们可以分配一个不同的对象。请注意下面的代码。首先,unique_ptr 指向 P1。但是,我们移除 P1 并用 P2 替换它,因此指针现在指向 P2。

Smart Pointer

C++ 代码

输出

50
50

2. shared_ptr

使用 shared_ptr,多个指针可以同时指向同一个对象,并且它将使用 use_count() 方法维护一个引用计数器。

Smart Pointer

C++ 代码

输出

50
50
50
2

3. weak_ptr

它与 shared_ptr 非常相似,不同之处在于它不维护引用计数器。在这种情况下,指针不会对对象有强引用。这样做的原因是,如果指针在请求其他对象时持有对象,它们可能会形成死锁。

Smart Pointer