C++ 中的智能指针(Smart Pointer)

news/2024/11/14 12:40:55/

C++ 中的智能指针(Smart Pointer)是用于管理动态内存分配的工具,它们能够自动管理资源的生命周期,避免内存泄漏。智能指针是 C++11 标准引入的,通过模板类封装原生指针,实现资源的自动释放。主要的智能指针包括 std::shared_ptrstd::unique_ptr

1. std::unique_ptr

std::unique_ptr 是一种独占所有权的智能指针,表示某个资源只能被一个指针管理。它确保同一资源在程序中只会有一个指针指向,当 std::unique_ptr 被销毁时,资源会被自动释放。

特点
  • 独占所有权std::unique_ptr 禁止拷贝操作,确保唯一所有权。
  • 自动释放资源:当 std::unique_ptr 超出作用域时,资源自动释放。
  • 移动语义:可以通过 std::move 转移所有权,但不能复制。
常用操作
  • 创建和使用:使用 std::make_unique 创建 std::unique_ptr
  • 访问资源:通过 operator*operator-> 访问资源。
  • 释放资源:可以使用 reset 手动释放资源。
示例代码
#include <iostream>
#include <memory> // 包含 unique_ptr 所在的头文件int main() {// 创建 unique_ptr 并指向一个动态分配的 intstd::unique_ptr<int> ptr = std::make_unique<int>(10);// 访问指针的值std::cout << "Value: " << *ptr << std::endl;// 不能复制 unique_ptr// std::unique_ptr<int> ptr2 = ptr;  // 错误// 可以通过移动语义转移所有权std::unique_ptr<int> ptr2 = std::move(ptr);if (!ptr) {std::cout << "ptr is now nullptr after moving ownership." << std::endl;}return 0;
}

输出

Value: 10
ptr is now nullptr after moving ownership.

2. std::shared_ptr

std::shared_ptr 是一种共享所有权的智能指针,允许多个指针共享同一个资源。std::shared_ptr 内部维护一个引用计数,记录有多少个 shared_ptr 指向该资源。当最后一个 shared_ptr 被销毁时,资源会自动释放。

特点
  • 共享所有权:多个 shared_ptr 可以指向同一个资源。
  • 引用计数:每个 shared_ptr 维护资源的引用计数。
  • 自动释放资源:当引用计数为 0 时,资源自动释放。
常用操作
  • 创建和使用:使用 std::make_shared 创建 std::shared_ptr
  • 访问资源:通过 operator*operator-> 访问资源。
  • 引用计数:通过 use_count 查看当前的引用计数。
示例代码
#include <iostream>
#include <memory> // 包含 shared_ptr 所在的头文件int main() {// 创建 shared_ptr 并指向一个动态分配的 intstd::shared_ptr<int> ptr1 = std::make_shared<int>(20);// 打印引用计数std::cout << "Reference count: " << ptr1.use_count() << std::endl;{// 创建一个新的 shared_ptr,指向相同资源std::shared_ptr<int> ptr2 = ptr1;std::cout << "Reference count after creating ptr2: " << ptr1.use_count() << std::endl;}// ptr2 超出作用域,引用计数减少std::cout << "Reference count after ptr2 goes out of scope: " << ptr1.use_count() << std::endl;return 0;
}

输出:

Reference count: 1
Reference count after creating ptr2: 2
Reference count after ptr2 goes out of scope: 1

3. std::weak_ptr

std::weak_ptr 是一种非拥有型的智能指针,用于解决 shared_ptr 的循环引用问题。它不会增加资源的引用计数,仅持有资源的一个弱引用,无法直接访问资源,需通过 lock 方法获得一个 shared_ptr 来使用。

示例代码
#include <iostream>
#include <memory>int main() {std::shared_ptr<int> sp = std::make_shared<int>(30);std::weak_ptr<int> wp = sp; // 使用 weak_ptr 指向同一资源std::cout << "Reference count: " << sp.use_count() << std::endl;if (auto spt = wp.lock()) { // 通过 lock 创建一个 shared_ptrstd::cout << "Weak pointer is valid, value: " << *spt << std::endl;} else {std::cout << "Weak pointer is expired." << std::endl;}sp.reset(); // 释放 shared_ptr 所有权if (wp.expired()) {std::cout << "Weak pointer is now expired." << std::endl;}return 0;
}

输出:

Reference count: 1
Weak pointer is valid, value: 30
Weak pointer is now expired.

总结

智能指针特点使用场景
std::unique_ptr独占所有权,不允许复制;可以通过 std::move 转移所有权需要独占管理资源,避免拷贝操作
std::shared_ptr共享所有权,使用引用计数管理资源的生命周期多个对象共享资源,需自动释放资源
std::weak_ptr非拥有型指针,不影响引用计数,用于解决循环引用问题检查或跟踪资源是否仍然存在

std::unique_ptrstd::shared_ptr 提供了简单、灵活的资源管理方式,有效降低内存泄漏风险。而 std::weak_ptr 主要用于防止 shared_ptr 的循环引用。


http://www.ppmy.cn/news/1546927.html

相关文章

docker安装minio、使用springboot集成minio同时创建并设置minio桶仅可读

docker-compose安装minio&#xff0c;并设置挂载目录 version: 3.8services:minio:image: minio/miniocontainer_name: minioenvironment:MINIO_ROOT_USER: rootMINIO_ROOT_PASSWORD: 123456789restarts: alwaysprivileged: trueports:- "9000:9000"- "9001:90…

在 MySQL 8.0 中,SSL 解密失败,在使用 SSL 加密连接时出现了问题

在 MySQL 8.0 中&#xff0c;SSL 解密失败通常指的是在使用 SSL 加密连接时出现了问题&#xff0c;导致无法建立加密通信。这个问题可能由多种原因引起&#xff0c;下面是一些常见的原因和排查方法&#xff1a; 1. 证书配置问题 确保您在 MySQL 配置中使用了正确的 SSL 证书和…

GitCode光引计划有奖征文大赛

一、活动介绍 GitCode平台汇聚了众多杰出的G-Star项目&#xff0c;它们犹如璀璨星辰&#xff0c;用各自的故事和成就&#xff0c;为后来者照亮前行的道路。我们诚邀广大开发者、项目维护者及爱好者&#xff0c;共同撰写并分享项目在GitCode平台上托管的体验&#xff0c;挖掘平…

汽车共享管理:SpringBoot技术的应用与挑战

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了共享汽车管理系统的开发全过程。通过分析共享汽车管理系统管理的不足&#xff0c;创建了一个计算机管理共享汽车管理系统的方案。文章介绍了共享汽车管理系统的系…

深入理解AIGC背后的核心算法:GAN、Transformer与Diffusion Models

深入理解AIGC背后的核心算法&#xff1a;GAN、Transformer与Diffusion Models 前言 随着人工智能技术的发展&#xff0c;AIGC&#xff08;AI Generated Content&#xff0c;人工智能生成内容&#xff09;已经不再是科幻电影中的幻想&#xff0c;而成为了现实生活中的一种新兴力…

火山引擎数据飞轮模式下的线上营销:内容产出更智能、人群触达更精准

今年年中&#xff0c;中欧国际工商学院等机构联合发布《2023 年中国首席营销官&#xff08;CMO&#xff09;调查报告》&#xff08;以下简称“报告”&#xff09;。 报告基于 167 家企业营销决策者调研&#xff0c;指出在激烈的市场竞争下&#xff0c;企业倾向于加强“拓新”策…

MYSQL中的两种转义操作

在 MySQL 中&#xff0c;转义字符用于处理特殊字符,以防止语法错误或 SQL 注入攻击,而单双引号都是需要重点注意的字符 可以用转义符\ 和 两个连续的引号 来起到转义引号的作用 转义符转义: 这是users表中的数据 如果查询admin 或者 admin" 用户,可以用转义符\ 两个连…

无效的目标发行版17和无法连接Maven进程问题

起因&#xff1a;我clean了一个模块的Maven想要重新下&#xff0c;他就开始报错。两次了都是这样。如果和我一样一开始都是好好的&#xff0c;直接找Maven的设置&#xff0c;在运行程序改&#xff0c;jre变成了11.它自己变成了我其他的jdk