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

【C++11】智能指针:std::shared_ptr

文章目录

  • 1. 计数指针 shared_ptr
  • 2. shared_ptr 与函数
  • 3. shared_ptr 与 unique_ptr

1. 计数指针 shared_ptr

shared_ptr 计数指针又称共享指针,是C++11引入的智能指针之一。与unique_ptr不同的是,shared_ptr允许多个指针共享同一块内存。每当一个shared_ptr 被赋值时,引用计数就会增加。当shraed_ptr被销毁时,引用计数会减小。当引用计数为0时,内存会被自动释放。

shared_ptr内部维护着一个引用计数器,可以通过 use_count() 获取当前引用计数。

代码示例:

#include <iostream>
#include <memory>
using namespace std;

int main(int argc, char *argv[]){

    std::shared_ptr<int> i_p_1 = make_shared<int>(10);
    cout<< "value: "<< *i_p_1 <<endl;
    cout<< "use count: "<<i_p_1.use_count() <<endl;

    // Copy
    std::shared_ptr<int> i_p_2 = i_p_1;
    cout<< "value: "<< *i_p_2<<endl;
    cout<< "i_p_1 use count: " << i_p_1.use_count() << endl;
    cout<< "i_p_2 use count: " << i_p_2.use_count() << endl;

    // 修改i_p_2的值
    *i_p_2 = 30;
    cout<< "i_p_1 value: " << *i_p_1 << endl;
    cout<< "i_p_2 value: " << *i_p_2 << endl;

    // i_p_1 设置为 nullptr
    std::shared_ptr<int> i_p_3 = i_p_1;
    // i_p_1 = nullptr;
    i_p_1.reset();
    cout<< "i_p_1 use count: " << i_p_1.use_count() << endl;
    cout<< "i_p_2 use count: " << i_p_2.use_count() << endl;
    cout<< "i_p_3 use count: " << i_p_3.use_count() << endl;

    return 0;
}

代码解析:

  • i_p_1 被初始化为一个 shared_ptr,指向整数10
  • i_p_2 是 i_p_1的副本,因此引用计数会增加
  • 修改了 i_p_2 的值,i_p_1也会变,因为他们共享一块内存
  • 当 i_p_1 被reset() 时,引用计数减少,最终,所有shared_ptr 被销毁时,内存会被自动释放。

2. shared_ptr 与函数

值传入
当 shared_ptr 作为函数参数传递时,默认是值传递(复制传递)。这会增加引用计数,确保指针在函数内部被正确管理。

#include <iostream>
#include <memory>
#include "cat.h"
using namespace std;

// 值传入
void cat_by_value(std::shared_ptr<Cat> cat){
    cout<< cat->get_name() <<endl;
    cat->set_cat_name("ee");
    cout<< "func use count :" << cat.use_count() << endl; // 2
}

// 引用传入
void cat_by_ref(std::shared_ptr<Cat> &cat){
    cout<< cat->get_name() <<endl;
    cat->set_cat_name("ff");
    cout<< "func use count :" << cat.use_count() << endl;
}

// 作为返回值
std::shared_ptr<Cat> get_shared_ptr(){
    std::shared_ptr<Cat> cat_p = std::make_shared<Cat>("local cat");
    return cat_p;
}

int main(int argc, char *argv[]){
    std::shared_ptr<Cat> c1 = make_shared<Cat>("dd");
    
    cat_by_value(c1);    // 值传递
    cat_by_ref(c1);         // 引用传递

    c1->cat_info();
    cout<< "c1 use_count : " << c1.use_count()<<endl; 
    
    // 返回值
    get_shared_ptr()->cat_info();

    return 0;
}

代码解析:

  • 值传递:当 shared_ptr 作为参数传递时,引用计数增加。函数结束时,局部 shared_ptr 会被销毁,引用计数会减少。
  • 引用传递:使用引用传递时,传递的是原始 shared_ptr,不会增加引用计数
  • 返回值:当 shared_ptr 作为返回值返回时,shared_ptr 会被复制到调用者

3. shared_ptr 与 unique_ptr

  • 不能将 shared_ptr 转化为 unique_ptr
  • unique_ptr 可以转化为 shared_ptr
    • 通过 std::move

常见的设计:

  • 将你的函数返回 unique_ptr 是一种常见的设计模式,这样可以提高代码的复用度,你可以随时改变为 shared_ptr

代码示例:

#include <iostream>
#include <memory>
#include "cat.h"
using namespace std;

std::unique_ptr<Cat> get_unique_ptr(){
    std::unique_ptr<Cat> cat_p = std::make_unique<Cat>("local cat");
    return cat_p;
}

int main(int argc, char *argv[]){
    std::unique_ptr<Cat> c_p_1 = std::make_unique<Cat>("dd");
    std::shared_ptr<Cat> c_p_2 = std::move(c_p_1);

    cout<< "c_p_2.use_count: " <<c_p_2.use_count()<<endl;

    std::shared_ptr<Cat> c_p_3 = get_unique_ptr(); 
    if(c_p_3){
        c_p_3->cat_info();
        cout<< "c_p_3.use_count: "<<c_p_3.use_count()<<endl;
    }

    return 0;
}

代码解析:

  • std::move 转换:c_p_1 是一个 unique_ptr,通过 std::move 将其所有权转移给 c_p_2,并转换为 shared_ptr。
  • unique_ptr 到 shared_ptr:返回的 unique_ptr 可以通过 std::move 转换为 shared_ptr,使得多个指针能够共享这块内存

相关文章:

  • FPGA设计中IOB约束
  • 【杂记四】刚体运动 +SE(3)
  • 【深度学习基础 1】 TensorFlow 框架
  • 插值法笔记 ——武汉理工统计 周
  • STM32 ADC和DAC详解
  • 使用 HBuilder 打包 ruoyi-mall-uniapp 并在微信开发者工具中模拟运行的教程
  • 第二章:影响优化的计算机行为_《C++性能优化指南》notes
  • Elasticsearch DSL查询语法
  • ES 字段的映射定义了字段的类型及其行为
  • 142. 环形链表 II——考察数学,难!
  • k8s存储介绍(二)Secret
  • 【AI News | 20250325】每日AI进展
  • 救生滚钩,高效救援的多功能生命守护者|鼎跃安全
  • 详解图卷积网络
  • 游戏引擎学习第183天
  • MyBatis-Plus缓存机制深度解析与SpringBoot整合实战
  • [c语言日寄MAX]深度解析:大小端字节序
  • 36.评论日记
  • MySQL颠覆版系列————MySQL新特性(开启数据库的新纪元)下篇
  • [Windows] 图吧工具箱
  • 广州北京网站建设公司哪家好/竞价排名是按照什么来计费的
  • ppt做的好的网站有哪些/上海牛巨仁seo
  • 铝合金型材外发加工网/福州网站优化公司
  • 盐城网站建设厂商/360网站推广官网
  • 做的网站一模一样会被告吗/清远网站seo
  • 重庆seo团队/aso如何优化