讲师中心 微信公众号
AI工具推荐 视频效率加速

c++中如何实现简单的垃圾回收机制_c++引用计数技术原理

大涛姑娘_6004

大涛姑娘_6004

发布时间:2026-01-09 16:54:01

|

435人浏览过

|

来源于php中文网

原创

C++标准不自带垃圾回收,因其坚持“零开销抽象”设计哲学;所谓GC实为手动模拟的引用计数智能指针(如std::shared_ptr),需用weak_ptr打破循环引用,且不适用于高频短生命周期场景。

c++中如何实现简单的垃圾回收机制_c++引用计数技术原理

为什么 C++ 标准不自带垃圾回收

C++ 的设计哲学是“零开销抽象”,newdelete 的行为完全由程序员控制,运行时无隐式内存管理开销。标准直到 C++11 才引入实验性 GC 接口(如 std::declare_reachable),但从未被主流实现启用,也未纳入语言核心机制。所以所谓“C++ 垃圾回收”,实际指**手动模拟的引用计数智能指针**,而非 Java/Python 那种后台扫描式 GC。

std::shared_ptr 是最常用的引用计数实现

它通过控制块(control block)独立记录引用计数与弱引用计数,对象生命周期由强引用数决定。关键点不是“自动释放”,而是“谁最后一个释放谁 delete”。

  • 构造时计数 +1,拷贝/赋值时计数 +1,析构/重置时计数 −1
  • 当强引用计数降为 0,自动调用 delete(或自定义删除器)
  • 循环引用会导致内存泄漏——shared_ptr 本身无法打破环,必须配合 weak_ptr
  • 控制块分配额外内存(通常一次 new 分配对象+控制块),有轻微性能开销
struct Node {
    std::shared_ptr<Node> next;
    ~Node() { std::cout << "Node destroyed\n"; }
};
<p>int main() {
auto a = std::make_shared<Node>();
auto b = std::make_shared<Node>();
a->next = b;  // 强引用
b->next = a;  // 循环引用 → a、b 永远不会析构
}

如何避免循环引用:用 weak_ptr 打破强引用环

weak_ptr 不增加强引用计数,只观察对象是否还存在。它不能直接访问对象,必须先调用 lock() 转成 shared_ptr,失败则说明对象已销毁。

  • weak_ptr 构造/拷贝不改变强计数,仅影响弱计数(用于控制块自身释放)
  • lock() 成功返回非空 shared_ptr,且此时强计数 +1;失败返回空 shared_ptr
  • 典型场景:树结构中父节点持子节点 shared_ptr,子节点用 weak_ptr 指向父节点
struct TreeNode {
    std::shared_ptr<TreeNode> parent;
    std::vector<std::shared_ptr<TreeNode>> children;
    // parent 是 weak_ptr,避免父子互相 hold
    std::weak_ptr<TreeNode> parent_weak;
<pre class='brush:php;toolbar:false;'>void set_parent(std::shared_ptr<TreeNode> p) {
    parent_weak = p; // 不增加 parent 的强引用计数
}

std::shared_ptr<TreeNode> get_parent() {
    return parent_weak.lock(); // 安全获取,可能为空
}

};

OC SSH Tunnel Node Recovery
OC SSH Tunnel Node Recovery

诊断并恢复通过 SSH 隧道连接的 OpenClaw 节点。用于解决配对必需错误、隧道冲突、远程端点错误以及 SSH 目标配置错误等问题。

下载

立即学习C++免费学习笔记(深入)”;

手写简易引用计数类要注意什么

除非教学或嵌入式极端受限场景,否则不要自己实现。但理解其原理有助于排查问题:

  • 计数变量必须是原子类型(如 std::atomic_int),否则多线程下 ++/-- 竞态
  • 控制块和对象最好分开分配,否则 delete 时无法定位控制块地址
  • 自定义删除器必须能访问控制块(例如通过虚函数或函数指针)
  • 禁止从裸指针重复构造多个计数对象(即不能对同一 new 出来的地址多次调用 make_shared 或自定义构造)

最容易被忽略的是:引用计数解决的是“谁负责释放”,不是“何时释放最高效”。在高频短生命周期对象场景(如游戏帧内临时数据),频繁原子操作反而比栈分配+手动清理更慢。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

更多
C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

299

2026.04.23

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

3028

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

4209

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3649

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

366

2026.01.19

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

4507

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2068

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

3438

2023.08.10

Conan私有仓库搭建教程
Conan私有仓库搭建教程

本专题系统的讲解Conan私有仓库的搭建流程,涵盖仓库服务部署、存储目录配置、用户认证、权限划分和远程地址添加,并介绍内部C++依赖包的上传、下载及版本维护方法。

0

2026.09.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn