8 C++ 智能指针之 shared_ptr 与 weak_ptr

在上一篇教程中,我们深入探讨了 unique_ptr 的使用,以及它如何在 C++ 中管理资源,防止内存泄漏。在本篇中,我们将重点关注 shared_ptrweak_ptr,这两种智能指针为实现共享和解决循环引用问题提供解决方案。

shared_ptr

shared_ptr 是一种共享所有权的智能指针,它允许多个指针实例共享同一块动态分配的内存。其底层使用引用计数的机制来管理资源的生命周期。

使用 shared_ptr

要使用 shared_ptr,需要包含头文件 <memory>。下面是一个使用 shared_ptr 的简单示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <memory>

class Resource {
public:
Resource() {
std::cout << "Resource acquired." << std::endl;
}
~Resource() {
std::cout << "Resource destroyed." << std::endl;
}
};

int main() {
std::shared_ptr<Resource> ptr1(new Resource());
{
std::shared_ptr<Resource> ptr2 = ptr1; // 共享所有权
std::cout << "ptr2 is created." << std::endl;
std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl; // 输出2
}
// ptr2 超出了作用域,资源不会立即释放
std::cout << "ptr2 is out of scope." << std::endl;
std::cout << "ptr1 use count: " << ptr1.use_count() << std::endl; // 输出1

return 0;
}

解析

在这个例子中,我们创建了一个 Resource 类的实例,并通过 shared_ptr 来管理它。ptr2 共享了 ptr1 的所有权,导致引用计数增加。当 ptr2 超出作用域后,引用计数减少,实际资源仍然由 ptr1 管理,直到 ptr1 也超出作用域。

循环引用问题

使用 shared_ptr 时,一个常见问题是循环引用。如果两个对象相互持有 shared_ptr,则它们的引用计数永远不会降到零,从而导致内存泄漏。为了解决这个问题,我们可以使用 weak_ptr

weak_ptr

weak_ptr 是一种不拥有对象的智能指针。它通常与 shared_ptr 配合使用,以避免循环引用问题。weak_ptr 允许访问由 shared_ptr 管理的资源,但不增加引用计数。

使用 weak_ptr

下面是一个示例,展示了如何使用 weak_ptr 来解决循环引用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <memory>

class B; // 前向声明

class A {
public:
std::shared_ptr<B> b_ptr; // 指向 B 的 shared_ptr
~A() {
std::cout << "A destroyed." << std::endl;
}
};

class B {
public:
std::weak_ptr<A> a_ptr; // 指向 A 的 weak_ptr
~B() {
std::cout << "B destroyed." << std::endl;
}
};

int main() {
std::shared_ptr<A> a = std::make_shared<A>();
std::shared_ptr<B> b = std::make_shared<B>();

a->b_ptr = b; // A 拥有 B
b->a_ptr = a; // B 指向 A,但不增加引用计数

std::cout << "End of the program." << std::endl;

return 0;
}

解析

在这个示例中,A 类持有指向 Bshared_ptr,而 B 类持有指向 Aweak_ptr。这样,AB 之间的循环引用得以避免。当 main 函数结束时,AB 的资源可以正确释放,没有内存泄漏。

总结

在本篇中,我们深入探讨了 shared_ptrweak_ptr 的使用,以及它们如何在 C++ 中共同工作以管理资源。在实际应用中,正常情况下,您可以使用 shared_ptr 来共享资源,而在处理可能导致循环引用的场景时使用 weak_ptr。这种方式提供了更安全、更方便的内存管理方案。

在下一篇教程中,我们将讨论如何自定义智能指针,为特定需求定制内存管理方案。感谢您阅读本篇教程!

8 C++ 智能指针之 shared_ptr 与 weak_ptr

https://zglg.work/c-plusplus-one/8/

作者

IT教程网(郭震)

发布于

2024-08-10

更新于

2024-08-22

许可协议

分享转发

交流

更多教程加公众号

更多教程加公众号

加入星球获取PDF

加入星球获取PDF

打卡评论