C++智能指针——weak_ptr详解

前言
  weak_ptr 设计的目的是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作, 它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造, 它的构造和析构不会引起引用记数的增加或减少.  同时weak_ptr 没有重载*和->但可以使用 lock 获得一个可用的 shared_ptr 对象。C++智能指针——share_ptr详解 使用陷阱中提到循环引用导致对象无法被析构的问题,通过weak_ptr可以解决

#ifndef testA_H
#define testA_H

#include <memory>
using namespace std;

class testB;
class testA {
    public:
    testA();
    ~testA();
    void testFunA(const shared_ptr<testB> &sptr);

    private:
    shared_ptr<testB> m_sptrB;
};
#endif

=====================================================================
#include "testA.h"
#include <iostream>
using namespace std;

testA::testA(){}

void testA::testFunA(const shared_ptr<testB> &sptr) {
    cout<<"testFunA"<<endl;
    m_sptrB = sptr;
}
testA::~testA(){
    cout<<"~testA destructor"<<endl;
}

=====================================================================
#ifndef testB_H
#define testB_H

#include <memory>

using namespace std;
class testA;
class testB {
    public:
    testB();
    ~testB();

    void testFunB(const shared_ptr<testA> &sptr);

    private:
    weak_ptr<testA>m_sptrA; //使用weak_ptr替换shared_ptr
};
#endif

=====================================================================
#include "testB.h"
#include <iostream>
using namespace std;

testB::testB(){}

void testB::testFunB(const shared_ptr<testA> &sptr) {
    cout<<"testFunB"<<endl;
    m_sptrA = sptr;
}

testB::~testB(){
    cout<<"~testB destructor"<<endl;
}

=====================================================================

int main(int argc, char const *argv[])
{
    testA *ta = new testA();
    testB *tb = new testB();
    shared_ptr<testA> sptra(ta);
    shared_ptr<testB> sptrb(tb);

    sptra->testFunA(sptrb);
    sptrb->testFunB(sptra);
}

输出结果:

testFunA
testFunA m_sptrB count = 2
testFunB
testFunB m_sptrA count = 1  //在testB类中用weak_ptr不会修改引用计数
~testA destructor
~testB destructor

weak_ptr常用函数介绍:

  • use_count函数,表示当前引用计数
  • reset函数,表示删除当前被管理的对象。
  • expired函数,表示判断被管理的对象是否被删除,相当于use_count()==0,如果被删除则返回true,否则返回false。
    shared_ptr<int> sptr(new int(2));
    weak_ptr<int> wptr(sptr);
    cout<<"wptr count = "<<wptr.use_count()<<endl;  //输出结果:1
    cout<<"wptr expired = "<<wptr.expired()<<endl;  //输出结果:0

    wptr.reset();
    cout<<"wptr count = "<<wptr.use_count()<<endl;  //输出结果:0
    cout<<"wptr expired = "<<wptr.expired()<<endl;  //输出结果:1

lock函数,该函数从资料上解释如下:

Lock and restore weak_ptr

Returns a shared_ptr with the information preserved by the weak_ptr object if it is not expired.

If the weak_ptr object has expired (including if it is empty), the function returns an empty shared_ptr (as if default-constructed).

Because shared_ptr objects count as an owner, this function locks the owned pointer, preventing it from being released (for at least as long as the returned object does not releases it).

This operation is executed atomically.

上述描述理解如下:

如果waak_ptr管理的对象不为空,则返回一个shared_ptr,否则返回一个空的 shared_ptr;此函数锁定所拥有的指针,防止其被释放。

    shared_ptr<int> sp1,sp2;
    weak_ptr<int> wp;
    sp1 = make_shared<int> (20);    // sp1
    wp = sp1;                       // sp1, wp

    cout<<"wp count = "<<wp.use_count()<<endl; count = 1

    sp2 = wp.lock();                // lock返回的是一个shared_ptr,赋值给sp2时引用计数加1

    cout<<"sp2 count = "<<sp2.use_count()<<endl;  count = 2
    cout<<"sp1 count = "<<sp1.use_count()<<endl;  count = 2

    sp1.reset();                    // 重置当前管理的指针,引用计数归零

    cout<<"sp1 count = "<<sp1.use_count()<<endl; count = 0
    cout<<"wp count = "<<wp.use_count()<<endl; count = 1,之前调用了lock防止被释放
    
    sp1 = wp.lock(); //wp.lock放回是shared_ptr,赋值之后引用计数加1 

    cout<<"sp1 count = "<<sp1.use_count()<<endl; count = 2
    cout<<"sp2 count = "<<sp2.use_count()<<endl; count = 2        
  • swap函数,表示交换weak_ptr管理对象和swap参数里边的内容。
    std::shared_ptr<int> sp1 (new int(10));
    std::shared_ptr<int> sp2 (new int(20));

    std::weak_ptr<int> wp1(sp1);
    std::weak_ptr<int> wp2(sp2);

    cout<<"wp1 = "<<*wp1.lock()<<endl;  // 10
    cout<<"wp2 = "<<*wp2.lock()<<endl;  // 20

    wp1.swap(wp2);

    cout<<"wp1 = "<<*wp1.lock()<<endl;  // 20
    cout<<"wp2 = "<<*wp2.lock()<<endl;  // 10

参考:http://www.cplusplus.com/reference/memory/weak_ptr/

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
shared_ptrC++中的智能指针,它采用引用计数的方法来实现释放指针所指向的资源。当使用shared_ptr时,它会记录有多少个shared_ptr指向同一个对象,只有当最后一个shared_ptr被销毁时,该对象的内存才会被释放。因此,shared_ptr可以自动管理内存,不需要手动释放。 在代码中,使用shared_ptr可以像普通指针一样操作对象。当需要创建一个shared_ptr对象时,可以使用std::make_shared函数来构造,如下所示: ``` std::shared_ptr<int> sharedPtr1 = std::make_shared<int>(10); ``` 可以通过将shared_ptr赋值给其他shared_ptr来共享资源,如下所示: ``` std::shared_ptr<int> sharedPtr2 = sharedPtr1; ``` 当所有的shared_ptr都被销毁时,内存会自动释放。可以使用use_count()函数获取shared_ptr的引用计数,如下所示: ``` std::cout << "sharedPtr2 use count: " << sharedPtr2.use_count() << std::endl; ``` 当引用计数为0时,内存会被自动释放。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++智能指针shared_ptr分析](https://download.csdn.net/download/weixin_38705004/13788082)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C++11中的智能指针unique_ptr、shared_ptrweak_ptr详解](https://blog.csdn.net/chenlycly/article/details/130918547)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值