shared_ptr和weak_ptr使用介绍

1 shared_ptr使用介绍

1.1 shared_ptr使用介绍

熟悉了unique_ptr 后,其实我们发现unique_ptr 这种排他型的内存管理并不能适应所有情况,有很大的局限!如果需要多个指针变量共享怎么办?

如果有一种方式,可以记录引用特定内存对象的智能指针数量,当复制或拷贝时,引用计数加1,当智能指针析构时,引用计数减1,如果计数为零,代表已经没有指针指向这块内存,那么我们就释放它!这就是 shared_ptr 采用的策略!

在这里插入图片描述
构造函数:

shared_ptr<T> sp ; //空的shared_ptr,可以指向类型为T的对象
shared_ptr<T> sp1(new T()) ;//定义shared_ptr,同时指向类型为T的对象
shared_ptr<T[]> sp2 ; //空的shared_ptr,可以指向类型为T[的数组对象 C++17后支持
shared_ptr<T[]> sp3(new T[]{...}) ;//指向类型为T的数组对象 C++17后支持
shared_ptr<T> sp4(NULL, D()); //空的shared_ptr,接受一个D类型的删除器,使用D释放内存
shared_ptr<T> sp5(new T(), D()); //定义shared_ptr,指向类型为T的对象,接受一个D类型的删除器,使用D删除器来释放内存

初始化:

// 方式一  构造函数
shared_ptrr<int> up1(new int(10));  //int(10) 的引用计数为1
shared_ptrr<int> up2(up1);  //使用智能指针up1构造up2, 此时int(10) 引用计数为2

// 方式二 使用make_shared 初始化对象,分配内存效率更高make_shared函数的主要功能是在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr; 用法:make_shared<类型>(构造类型对象需要的参数列表); 
shared_ptr<int> p4 = make_shared<int>(2); //多个参数以逗号','隔开,最多接受十个
shared_ptr<string> p4 = make_shared<string>("字符串");

赋值:

shared_ptrr<int> up1(new int(10));  //int(10) 的引用计数为1
shared_ptr<int> up2(new int(11));   //int(11) 的引用计数为1
up1 = up2;//int(10) 的引用计数减1,计数归零内存释放,up2共享int(11)给up1, int(11)的引用计数为2

主动释放对象:

shared_ptrr<int> up1(new int(10));
up1 = nullptr ;//int(10) 的引用计数减1,计数归零内存释放 
up1 = NULL; //作用同上 

重置:

up.reset() ;    //将p重置为空指针,所管理对象引用计数减1
up.reset(p1);   //将p重置为p1(的值),p 管控的对象计数减1,p接管对p1指针的管控
up.reset(p1,d);  //将p重置为p(的值),p 管控的对象计数减1并使用d作为删除器

交换:

std::swap(p1,p2); //交换p1 和p2 管理的对象,原对象的引用计数不变
p1.swap(p2);    //同上

1.2 shared_ptr的使用陷阱

shared_ptr作为被管控的对象的成员时,小心因循环引用造成无法释放资源!

示例代码如下:

#include <stdio.h>
#include <iostream>
#include <string>
#include <memory>
#include <vector>

using namespace std;

class girl;

class boy {
public:
    boy() {
        cout << "boy construct!" << endl;
    }

    ~boy() {
        cout << "boy destruct!" << endl;
    }

    void set_girl_friend(shared_ptr<girl> &g) {
        girl_friend = g;
    }
private:
    shared_ptr<girl> girl_friend;
};

class girl {
public:
    girl() {
        cout << "girl construct!" << endl;
    }

    ~girl() {
        cout << "girl destruct!" << endl;
    }

    void set_boy_friend(shared_ptr<boy> &b) {
        boy_friend = b;
    }
private:
    shared_ptr<boy> boy_friend;
};


void use_trap() {
    shared_ptr<girl> sp_girl(new girl());//白娘子
    shared_ptr<boy> sp_boy(new boy());  //许仙

    sp_girl->set_boy_friend(sp_boy);
    sp_boy->set_girl_friend(sp_girl);

}

int main() {

	use_trap();
	system("pause");
	return 0;
}

2 weak_ptr使用简介

weak_ptr 设计的目的是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作, 它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造, 它的构造和析构不会引起引用记数的增加或减少。同时weak_ptr 没有重载*和->,但可以使用 lock 获得一个可用的 shared_ptr 对象(引用计数会增加1)。

一般情况下我们无需使用weak_ptr,只有在特殊的情况下才需要使用weak_ptr!


参考资料:

  1. C/C++从入门到精通-高级程序员之路【奇牛学院】
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读