0

0

如何在C++中实现引用计数智能指针 手写简化版shared_ptr示例

P粉602998670

P粉602998670

发布时间:2025-07-10 14:24:02

|

187人浏览过

|

来源于php中文网

原创

实现一个简化版的c++++引用计数智能指针(类似shared_ptr)的核心步骤包括:设计包含资源指针和引用计数的类,实现构造函数、拷贝构造函数、析构函数和赋值操作符重载,以及提供获取原始指针和解引用的操作符。2. 构造函数初始化资源并设置初始引用计数为1;拷贝构造函数使新对象共享资源并递增引用计数;析构函数递减引用计数并在其变为0时释放资源;赋值操作符处理自我赋值并正确释放旧资源后接管新资源。3. 通过重载*和->操作符以支持指针访问语义,并提供use_count方法查看当前引用计数值。4. 示例代码演示了该智能指针的基本用法及引用计数的变化过程,验证了其核心机制的有效性。

如何在C++中实现引用计数智能指针 手写简化版shared_ptr示例

在C++中,实现一个简化版的引用计数智能指针(类似shared_ptr)可以帮助你理解其底层机制。下面会一步步带你写一个基础版本,虽然不考虑线程安全、自定义删除器等复杂情况,但足以展示核心原理。

如何在C++中实现引用计数智能指针 手写简化版shared_ptr示例

基本结构设计

要实现一个带有引用计数的智能指针,我们需要两个关键部分:

如何在C++中实现引用计数智能指针 手写简化版shared_ptr示例
  • 一个资源管理类,用来持有实际的对象指针;
  • 一个引用计数管理类,记录当前有多少个智能指针指向这个资源。

我们可以用一个结构体来保存这些信息:

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

template
class RefCountedPtr {
private:
    struct ControlBlock {
        T* ptr;
        int* ref_count;

        ControlBlock(T* p) : ptr(p), ref_count(new int(1)) {}
        ~ControlBlock() {
            delete ptr;
            delete ref_count;
        }
    };

    ControlBlock control_block;
};

当然这只是骨架,后面我们会把它封装成更像shared_ptr的形式。

如何在C++中实现引用计数智能指针 手写简化版shared_ptr示例

实现构造与析构逻辑

我们要让多个智能指针共享同一个资源,并在最后一个指针被销毁时释放内存。

10Web
10Web

AI驱动的WordPress网站自动构建器,托管和页面速度助推器

下载

构造函数

构造函数负责初始化资源和引用计数:

template
class SimpleSharedPtr {
private:
    T* ptr;
    int* ref_count;

public:
    explicit SimpleSharedPtr(T* p = nullptr)
        : ptr(p), ref_count(new int(1)) {}

    // ...
};

拷贝构造函数

拷贝构造函数需要让新对象指向同一资源,并增加引用计数:

SimpleSharedPtr(const SimpleSharedPtr& other)
    : ptr(other.ptr), ref_count(other.ref_count) {
    ++(*ref_count);
}

析构函数

当引用计数变为0时才真正释放资源:

~SimpleSharedPtr() {
    if (--(*ref_count) == 0) {
        delete ptr;
        delete ref_count;
    }
}

赋值操作符重载

赋值操作要考虑自我赋值和旧资源释放的问题:

SimpleSharedPtr& operator=(const SimpleSharedPtr& other) {
    if (this != &other) {
        // 先减少当前引用计数
        if (--(*ref_count) == 0) {
            delete ptr;
            delete ref_count;
        }

        // 接管对方资源
        ptr = other.ptr;
        ref_count = other.ref_count;
        ++(*ref_count);
    }
    return *this;
}

获取原始指针和解引用操作

为了让我们的智能指针像普通指针一样使用,还需要重载一些操作符:

T& operator*() const { return *ptr; }
T* operator->() const { return ptr; }

T* get() const { return ptr; }

示例代码完整版

下面是简化版shared_ptr的一个最小可用实现:

#include 

template
class SimpleSharedPtr {
private:
    T* ptr;
    int* ref_count;

public:
    explicit SimpleSharedPtr(T* p = nullptr)
        : ptr(p), ref_count(new int(1)) {}

    SimpleSharedPtr(const SimpleSharedPtr& other)
        : ptr(other.ptr), ref_count(other.ref_count) {
        ++(*ref_count);
    }

    SimpleSharedPtr& operator=(const SimpleSharedPtr& other) {
        if (this != &other) {
            if (--(*ref_count) == 0) {
                delete ptr;
                delete ref_count;
            }

            ptr = other.ptr;
            ref_count = other.ref_count;
            ++(*ref_count);
        }
        return *this;
    }

    ~SimpleSharedPtr() {
        if (--(*ref_count) == 0) {
            delete ptr;
            delete ref_count;
        }
    }

    T& operator*() const { return *ptr; }
    T* operator->() const { return ptr; }

    int use_count() const { return *ref_count; }
};

int main() {
    SimpleSharedPtr p1(new int(42));
    std::cout << "Use count: " << p1.use_count() << std::endl; // 输出 1

    {
        SimpleSharedPtr p2 = p1;
        std::cout << "Use count: " << p1.use_count() << std::endl; // 输出 2
    }

    std::cout << "Use count after p2 destroyed: " << p1.use_count() << std::endl; // 输出 1
    return 0;
}

基本上就这些了。
这个版本没有考虑线程安全、自定义删除器、数组支持等功能,但在学习理解引用计数机制上已经足够。

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

194

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

186

2025.07.04

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

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

472

2023.08.10

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

65

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

45

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

40

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

41

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

232

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

9

2025.12.31

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号