【C++11】shared_ptr

目的

  1. 多个智能指针共同管理同一块内存
  2. 其核心是引用计数,每使用它一次,内部引用计数加1,每析构一次内部的引用计数减1,减为0时,删除所指向的堆内存

表示方式

  1. 共享智能指针的初始化
    a. 共享智能指针构造函数
    shared<类型> 智能指针名(内存)
    int *ptr = new int(500);
    shared_ptr<int> ptr1(ptr);//指向int型内存,shared<类型> 智能指针名(内存)
    shared_ptr<char> ptr2(new char[20]);//使用智能指针管理一块字符数组对应的堆内存
    shared_ptr<int> ptr3;//创建智能指针,但不初始化任何内存
    shared_ptr<int> ptr4(nullptr);/创建智能指针,初始化为空
    
    b. 移动构造和拷贝构造函数
    //移动构造
    shared_ptr<int> move_ptr = move(ptr1);
    //拷贝构造
    shared_ptr<int> copy_ptr = move_ptr;
    
    c. make_shared函数
    //make_shared<类型>(数值)
    shared_ptr<int> makeshare_ptr = make_shared<int>(10);
    
    d. reset()初始化
    class_ptr1.reset();//无参数表示只删除,不重定义初始化
    class_ptr2.reset(new Test("szy"));//先删除,再重定义初始化
    
  2. 共享智能指针的使用方法
    a. 共享智能智能指针的引用计数
    .use_count():查看当前共享智能指针的引用计数
    shared_ptr<int> ptr1(ptr);
    cout << "ptr1的值:" << *ptr1 << ",ptr1管理的内存引用计数:" << ptr1.use_count() << endl;
    
    b. 获取原始指针
    .get():获取原始指针
    //获取原始指针,通过get()方法获取地址,*获取值
    Test* t = class_ptr2.get();//get()智能指针的成员函数,通过.获取
    t->setValue(22);
    t->display();
    
    c. 直接使用智能指针
    与.get()方法的区别是 .获取 和 ->获取
    //直接通过智能指针访问
    class_ptr2->setValue(44);//指针方式->获取
    class_ptr2->display();
    
  3. 共享智能指针的删除器
    尽管智能指针可以通过默认删除器自动释放内存,但对于数组类型,默认删除器是无法完全释放数组中的所有元素,因此需要对默认删除器指定数组类型。
    删除器也可以自定义匿名函数实现
    C++11中不支持管理数组地址,但C++11之后支持
    //针对数组类型需要传入数组类型,否则默认删除器无法删除数字中的每一个元素
    shared_ptr<Test> arr_ptr(new Test[3], default_delete<Test[]>());
    

细节

  1. 引用计数减为0时,会删除所指向的堆内存
  2. 只声明共享智能指针,不做初始化时,该共享智能指针的引用计数为0
  3. 移动构造和拷贝构造都会增加引用计数
  4. 使用智能指针时,->箭头方式调用的是管理的这块内存对应的对象里面的api;.点方式调用的智能指针对象里面的api,这两个api是属于不同的类中的

举例

//如果智能指针被初始化了一块有效内存,那么这块内存的引用计数 + 1,如果智能指针没有被初始化或者被初始化为 nullptr 空指针,引用计数不会 + 1。
#include <bits/stdc++.h>
using namespace std;
class Test
{
public:
    Test() 
    {
        cout << "construct Test..." << endl;
    }
    Test(int x) 
    {
        cout << "construct Test, x = " << x << endl;
    }
    Test(string str) 
    {
        cout << "construct Test, str = " << str << endl;
    }
    ~Test()
    {
        cout << "destruct Test ..." << endl;
    }
    void setValue(int v){
        m_num = v;
    }
    void display(){
        cout << "成员变量m_num:" << m_num << endl;
    }
private:
    int m_num;
};

int main(){
    //普通指针,指针的数值为500
    int *ptr = new int(500);
    cout << *ptr << endl;

    cout << "-----------------------共享智能指针通过构造函数进行初始化-------------------------" << endl;
    //指向int型内存,shared<类型> 智能指针名(内存)
    shared_ptr<int> ptr1(ptr);
    cout << "ptr1的值:" << *ptr1 << ",ptr1管理的内存引用计数:" << ptr1.use_count() << endl;
    //使用智能指针管理一块字符数组对应的堆内存
    shared_ptr<char> ptr2(new char[20]);
    cout << "ptr2管理的内存引用计数:" << ptr2.use_count() << endl;
    //创建智能指针,但不初始化任何内存
    shared_ptr<int> ptr3;
    cout << "ptr3管理的内存引用计数:" << ptr3.use_count() << endl;
    //创建智能指针,初始化为空
    shared_ptr<int> ptr4(nullptr);
    cout << "ptr4管理的内存引用计数:" << ptr4.use_count() << endl;

    cout << "-----------------------共享智能指针通过移动构造和拷贝构造函数进行初始化-------------------------" << endl;
    //移动构造
    shared_ptr<int> move_ptr = move(ptr1);
    // cout << "ptr1的值:" << *ptr1 << ",ptr1管理的内存引用计数:" << ptr1.use_count() << endl;//error:此时ptr1中的资源已经全部转移到了move_ptr中
    cout << "move_ptr的值:" << *move_ptr << ",move_ptr管理的内存引用计数:" << move_ptr.use_count() << endl;
    //拷贝构造
    shared_ptr<int> copy_ptr = move_ptr;
    cout << "move_ptr的值:" << *move_ptr << ",move_ptr管理的内存引用计数:" << move_ptr.use_count() << endl;
    cout << "copy_ptr的值:" << *copy_ptr << ",copy_ptr管理的内存引用计数:" << copy_ptr.use_count() << endl;

    cout << "-----------------------共享智能指针通过make_shared进行初始化-------------------------" << endl;
    shared_ptr<int> makeshare_ptr = make_shared<int>(10);//make_shared<类型>(数值)
    cout << "makeshare_ptr的值:" << *makeshare_ptr << ",makeshare_ptr管理的内存引用计数:" << makeshare_ptr.use_count() << endl;
    shared_ptr<Test> class_ptr1 = make_shared<Test>(30);
    shared_ptr<Test> class_ptr2 = make_shared<Test>("llx");

    cout << "-----------------------共享智能指针通过reset进行初始化-------------------------" << endl;
    class_ptr1.reset();
    cout << "class_ptr1重置指针后的的内存引用计数:" << class_ptr1.use_count() << endl;
    class_ptr2.reset(new Test("szy"));
    cout << "class_ptr2管理的内存引用计数:" << class_ptr2.use_count() << endl;

    cout << "-----------------------使用共享智能指针-------------------------" << endl;
    //获取原始指针,通过get()方法获取地址,*获取值
    Test* t = class_ptr2.get();//get()智能指针的成员函数,通过.获取
    t->setValue(22);
    t->display();
    //直接通过智能指针访问
    class_ptr2->setValue(44);//指针方式->获取
    class_ptr2->display();

    cout << "-----------------------共享智能指针删除器-------------------------" << endl;
    //针对数组类型需要传入数组类型,否则默认删除器无法删除数字中的每一个元素
    shared_ptr<Test> arr_ptr(new Test[3], default_delete<Test[]>());
    // system("pause");
    return 0;
}

运行结果

在这里插入图片描述

参考学习

https://www.bilibili.com/video/BV1bX4y1G7ks

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值