shared_ptr八股收集 C++

(1)、具体讲一下shared_ptr自动管理内存的原理/引用计数的具体原理/shared_ptr引用计数什么时候会增加,什么时候会减少?

在shared_ptr的内部维护了⼀个计数器,来跟踪有多少个shared_ptr对象指向了某⼀个资源。当计数器的值减少到0的时候,shared_ptr就会调⽤delete(或者⽤户⾃定义的⽅法)来释放资源。

引用计数器何时增加:

1.新建⼀个shared_ptr并指向了⼀个资源时。

2.复制构造函数创建⼀个新的shared_ptr时。

3.⽤复制运算符将⼀个shared_ptr给另⼀个shared_ptr对象赋值时。

引⽤计数器何时减少:

1.当⼀个shared_ptr对象被销毁时,⽐如局部变量离开作⽤域,或者类成员变量析构时。

2.当⼀个shared_ptr对象不再指向⼀个资源时,例如通过reset⽅法或者赋值运算符指向另⼀个资源时。

(2)、shared_ptr是线程安全的吗

1、多线程代码操作的是同一个shared_ptr的对象是线程不安全的。

2、多线程代码操作的不是同一个shared_ptr的对象,但不同的shared_ptr指向了相同的内存,此时是线程安全的。

2、多线程情况下,管理同一个数据的shared_ptr在进行计数的增加和减少时是原子操作,是线程安全的。

(3)、手撕一下shared_ptr

(4)、

1. 基本原理说明(先讲理论再写代码)

"shared_ptr 是一种共享所有权的智能指针,通过引用计数机制管理对象的生命周期。多个 shared_ptr 可以指向同一个对象,当最后一个 shared_ptr 被销毁时,对象才会被删除。"

2. 关键组件

"它需要维护两个核心数据成员:

  • 原始指针 T* ptr

  • 引用计数 int* ref_count(必须用指针,所有实例共享)

引用计数必须放在堆上,因为多个 shared_ptr 需要共享同一个计数器。"

3. 必须实现的成员函数

在写代码时,至少要包含以下核心实现:

复制代码
template <typename T>
class SharedPtr {
private:
    T* ptr;
    int* ref_count;
    
    void release() {
        if (ref_count && --(*ref_count) == 0) {
            delete ptr;
            delete ref_count;
        }
    }
public:
    // 1. 构造函数
    explicit SharedPtr(T* p = nullptr) 
        : ptr(p), ref_count(p ? new int(1) : nullptr) {}
    
    // 2. 拷贝构造函数
    SharedPtr(const SharedPtr& other)
        : ptr(other.ptr), ref_count(other.ref_count) {
        if (ref_count) ++(*ref_count);
    }
    
    // 3. 移动构造函数
    SharedPtr(SharedPtr&& other) noexcept
        : ptr(other.ptr), ref_count(other.ref_count) {
        other.ptr = nullptr;
        other.ref_count = nullptr;
    }
    
    // 4. 析构函数
    ~SharedPtr() { release(); }
    
    // 5. 拷贝赋值
    SharedPtr& operator=(const SharedPtr& other) {
        if (this != &other) {
            release();
            ptr = other.ptr;
            ref_count = other.ref_count;
            if (ref_count) ++(*ref_count);
        }
        return *this;
    }
    
    // 6. 移动赋值
    SharedPtr& operator=(SharedPtr&& other) noexcept {
        if (this != &other) {
            release();
            ptr = other.ptr;
            ref_count = other.ref_count;
            other.ptr = nullptr;
            other.ref_count = nullptr;
        }
        return *this;
    }
    
    // 7. 解引用操作符
    T& operator*() const { return *ptr; }
    T* operator->() const { return ptr; }
    
    // 8. 辅助函数
    int use_count() const { return ref_count ? *ref_count : 0; }
    void reset(T* p = nullptr) { /* 实现重置逻辑 */ }
};
相关推荐
tan180°2 小时前
MySQL表的操作(3)
linux·数据库·c++·vscode·后端·mysql
彭祥.3 小时前
Jetson边缘计算主板:Ubuntu 环境配置 CUDA 与 cudNN 推理环境 + OpenCV 与 C++ 进行目标分类
c++·opencv·分类
lzb_kkk4 小时前
【C++】C++四种类型转换操作符详解
开发语言·c++·windows·1024程序员节
胖大和尚5 小时前
clang 编译器怎么查看在编译过程中做了哪些优化
c++·clang
钱彬 (Qian Bin)6 小时前
一文掌握Qt Quick数字图像处理项目开发(基于Qt 6.9 C++和QML,代码开源)
c++·开源·qml·qt quick·qt6.9·数字图像处理项目·美观界面
双叶8367 小时前
(C++)学生管理系统(正式版)(map数组的应用)(string应用)(引用)(文件储存的应用)(C++教学)(C++项目)
c语言·开发语言·数据结构·c++
源代码•宸7 小时前
C++高频知识点(二)
开发语言·c++·经验分享
jyan_敬言9 小时前
【C++】string类(二)相关接口介绍及其使用
android·开发语言·c++·青少年编程·visual studio
liulilittle9 小时前
SNIProxy 轻量级匿名CDN代理架构与实现
开发语言·网络·c++·网关·架构·cdn·通信
tan77º10 小时前
【Linux网络编程】Socket - UDP
linux·服务器·网络·c++·udp