当前位置: 首页 > news >正文

C++智能指针使用指南(auto_ptr, unique_ptr, shared_ptr, weak_ptr)

在 C++ 中,智能指针是管理动态分配内存的重要工具,它们可以自动释放内存,避免内存泄漏。以下是四种主要智能指针的详细介绍:

1. auto_ptr (已废弃)

基本特性

  • C++98 引入,C++17 中已移除

  • 具有所有权转移语义

示例代码

cpp

#include <memory>
#include <iostream>void autoPtrExample() {std::auto_ptr<int> p1(new int(10));std::cout << *p1 << std::endl;  // 输出: 10std::auto_ptr<int> p2 = p1;  // 所有权转移// std::cout << *p1 << std::endl;  // 错误!p1 现在为空std::cout << *p2 << std::endl;  // 输出: 10
}

问题

  • 所有权转移不明确,容易导致错误

  • 不支持数组

  • 不能在 STL 容器中使用

2. unique_ptr (C++11)

基本特性

  • 独占所有权,不能拷贝,只能移动

  • 轻量级,无额外开销

  • 支持自定义删除器

  • 支持数组

示例代码

cpp

#include <memory>
#include <iostream>void uniquePtrExample() {// 基本用法std::unique_ptr<int> p1(new int(20));std::cout << *p1 << std::endl;  // 输出: 20// 移动语义std::unique_ptr<int> p2 = std::move(p1);std::cout << *p2 << std::endl;  // 输出: 20// p1 现在为空// 使用 make_unique (C++14)auto p3 = std::make_unique<int>(30);// 数组支持auto p4 = std::make_unique<int[]>(5);p4[0] = 1;p4[1] = 2;// 自定义删除器auto deleter = [](int* p) {std::cout << "Deleting int: " << *p << std::endl;delete p;};std::unique_ptr<int, decltype(deleter)> p5(new int(50), deleter);
}

3. shared_ptr (C++11)

基本特性

  • 共享所有权,使用引用计数

  • 支持拷贝和赋值

  • 线程安全(引用计数操作)

  • 支持自定义删除器

示例代码

cpp

#include <memory>
#include <iostream>class MyClass {
public:MyClass(int val) : value(val) {std::cout << "MyClass constructed: " << value << std::endl;}~MyClass() {std::cout << "MyClass destroyed: " << value << std::endl;}void print() {std::cout << "Value: " << value << std::endl;}private:int value;
};void sharedPtrExample() {// 创建 shared_ptrstd::shared_ptr<MyClass> p1 = std::make_shared<MyClass>(100);
rd.xjyl.gov.cn/upload/1982074929729208321.html
rd.xjyl.gov.cn/upload/1982074929775345664.html
rd.xjyl.gov.cn/upload/1982074929792122880.html
rd.xjyl.gov.cn/upload/1982074929871814656.html
rd.xjyl.gov.cn/upload/1982074929980866560.html
rd.xjyl.gov.cn/upload/1982074930068946944.html
rd.xjyl.gov.cn/upload/1982074930337382400.html
rd.xjyl.gov.cn/upload/1982074930408685568.html
rd.xjyl.gov.cn/upload/1982074930429657088.html
rd.xjyl.gov.cn/upload/1982074930551291904.html
rd.xjyl.gov.cn/upload/1982074930614206464.html
rd.xjyl.gov.cn/upload/1982074930635177984.html
rd.xjyl.gov.cn/upload/1982074930706481152.html
rd.xjyl.gov.cn/upload/1982074930719064064.html
rd.xjyl.gov.cn/upload/1982074931075579904.html
rd.xjyl.gov.cn/upload/1982074931146883072.html
rd.xjyl.gov.cn/upload/1982074931247546368.html
rd.xjyl.gov.cn/upload/1982074931247546369.html
rd.xjyl.gov.cn/upload/1982074931373375488.html
rd.xjyl.gov.cn/upload/1982074931369181185.html
rd.xjyl.gov.cn/upload/1982074931369181184.html
rd.xjyl.gov.cn/upload/1982074931570507776.html
rd.xjyl.gov.cn/upload/1982074931604062208.html
rd.xjyl.gov.cn/upload/1982074931725697024.html{std::shared_ptr<MyClass> p2 = p1;  // 引用计数 +1p2->print();std::cout << "Use count: " << p1.use_count() << std::endl;  // 输出: 2}  // p2 析构,引用计数 -1std::cout << "Use count: " << p1.use_count() << std::endl;  // 输出: 1p1->print();// 自定义删除器std::shared_ptr<MyClass> p3(new MyClass(200), [](MyClass* p) {std::cout << "Custom deleter called" << std::endl;delete p;});
}

4. weak_ptr (C++11)

基本特性

  • 不拥有对象所有权

  • 解决 shared_ptr 循环引用问题

  • 必须从 shared_ptr 创建

循环引用问题示例

cpp

#include <memory>
#include <iostream>class Node {
public:std::shared_ptr<Node> next;std::shared_ptr<Node> prev;~Node() {std::cout << "Node destroyed" << std::endl;}
};void circularReferenceProblem() {auto node1 = std::make_shared<Node>();auto node2 = std::make_shared<Node>();node1->next = node2;  // 循环引用node2->prev = node1;  // 内存泄漏!// node1 和 node2 的引用计数永远不会为 0
}

使用 weak_ptr 解决循环引用

cpp

class NodeSafe {
public:std::shared_ptr<NodeSafe> next;std::weak_ptr<NodeSafe> prev;  // 使用 weak_ptr~NodeSafe() {std::cout << "NodeSafe destroyed" << std::endl;
rd.xjyl.gov.cn/upload/1982074931901857792.html
rd.xjyl.gov.cn/upload/1982074931914440704.html
rd.xjyl.gov.cn/upload/1982074932023492608.html
rd.xjyl.gov.cn/upload/1982074932027686912.html
rd.xjyl.gov.cn/upload/1982074932086407168.html
rd.xjyl.gov.cn/upload/1982074932115767296.html
rd.xjyl.gov.cn/upload/1982074932203847680.html
rd.xjyl.gov.cn/upload/1982074932262567936.html
rd.xjyl.gov.cn/upload/1982074932291928064.html
rd.xjyl.gov.cn/upload/1982074932317093888.html
rd.xjyl.gov.cn/upload/1982074932392591360.html
rd.xjyl.gov.cn/upload/1982074932367425536.html
rd.xjyl.gov.cn/upload/1982074932392591361.html
rd.xjyl.gov.cn/upload/1982074932640055296.html
rd.xjyl.gov.cn/upload/1982074932661026816.html
rd.xjyl.gov.cn/upload/1982074932728135680.html
rd.xjyl.gov.cn/upload/1982074932954628096.html
rd.xjyl.gov.cn/upload/1982074932958822400.html
rd.xjyl.gov.cn/upload/1982074933034319872.html
rd.xjyl.gov.cn/upload/1982074933306949632.html
rd.xjyl.gov.cn/upload/1982074933361475584.html
rd.xjyl.gov.cn/upload/1982074933424390144.html
rd.xjyl.gov.cn/upload/1982074933432778752.html
rd.xjyl.gov.cn/upload/1982074933508276224.html
rd.xjyl.gov.cn/upload/1982074933596356608.html
rd.xjyl.gov.cn/upload/1982074933575385088.html}
};void weakPtrSolution() {auto node1 = std::make_shared<NodeSafe>();auto node2 = std::make_shared<NodeSafe>();node1->next = node2;node2->prev = node1;  // 不会增加引用计数// 可以正常析构,无内存泄漏
}void weakPtrUsage() {auto shared = std::make_shared<int>(42);std::weak_ptr<int> weak = shared;// 检查对象是否还存在if (auto locked = weak.lock()) {std::cout << "Object exists: " << *locked << std::endl;} else {std::cout << "Object has been destroyed" << std::endl;}shared.reset();  // 释放对象if (auto locked = weak.lock()) {std::cout << "Object exists: " << *locked << std::endl;} else {std::cout << "Object has been destroyed" << std::endl;}
}

最佳实践总结

  1. 优先使用 unique_ptr

    • 默认选择,性能最好

    • 明确表达独占所有权

  2. 需要共享所有权时使用 shared_ptr

    • 多个对象需要访问同一资源

    • 注意避免循环引用

  3. 使用 weak_ptr 打破循环引用

    • 观察者模式

    • 缓存场景

  4. 使用 make_shared 和 make_unique

    • 更安全,避免显式 new

    • 更好的性能(make_shared)

  5. 避免使用 auto_ptr

    • 已被废弃,使用 unique_ptr 替代

完整示例

cpp

#include <memory>
#include <iostream>
#include <vector>int main() {// unique_ptr 示例std::unique_ptr<int> unique = std::make_unique<int>(10);// shared_ptr 示例std::shared_ptr<int> shared1 = std::make_shared<int>(20);std::shared_ptr<int> shared2 = shared1;// weak_ptr 示例std::weak_ptr<int> weak = shared1;// 在容器中使用智能指针std::vector<std::shared_ptr<int>> vec;vec.push_back(std::make_shared<int>(1));vec.push_back(std::make_shared<int>(2));vec.push_back(std::make_shared<int>(3));for (const auto& ptr : vec) {std::cout << *ptr << " ";}std::cout << std::endl;return 0;
}

智能指针是现代 C++ 内存管理的核心工具,正确使用可以显著提高代码的安全性和可维护性。

http://www.dtcms.com/a/529059.html

相关文章:

  • GitHub等平台形成的开源文化正在重塑知可以谈人
  • 计算机网络:知识点梳理及讲解(三)数据链路层
  • PySide6 pyside6-deploy 命令 Linux 部署
  • 网站内的搜索怎么做的学校网站建设情况报告
  • 电脑建立网站朝阳区手机网站建设服务
  • 谷歌商店下载APK教程,先下载谷歌三件套,再直接从 Google Play 下载 APK 文件?
  • Spring中事务的传播行为
  • 将镜像推送到 Docker Hub 或私有仓库
  • 做qq图片的网站吗wordpress没有链接地址
  • 面向模块的综合技术之重定时优化(六)
  • 社交模板网站建设成都青羊网站建设
  • Android 数据持久化(SharedPreferences)
  • 四、高效注意力机制与模型架构
  • 沧州做网站公司兰州网站建站
  • C++ STL:string类(1) |了解string|编码|常用接口|迭代器|算法查找|auto|范围for
  • ESP32 Linux 开发环境
  • 网站建设全国排名alexa排名前三十
  • 声乐基础知识学习
  • Redis底层原理-持久化【详细易懂】
  • 现在建网站可以拖拉式的吗深圳住房建设网站
  • 流量打不开网站怎么办营销型企业网站 网络服务
  • 如何用ps做网站ui如何在云主机上建设网站
  • 营销网站建设818gx做商城网站多少钱
  • 【C/C++】动态加载(dlopen)和直接链接 库的区别
  • 集团内部协同项目管理模式整理表
  • 基于yolov11的机场跑道异物检测系统python源码+pytorch模型+训练数据集+精美GUI界面
  • 【开题答辩全过程】以 滨海游泳馆管理系统为例,包含答辩的问题和答案
  • 阿里云网站实名认证设备租赁业务网站如何做
  • 2025年9月电子学会全国青少年软件编程等级考试(scratch图形化四级)真题及答案
  • 中国万网icp网站备案专题wordpress播放器问题