C++11新特性 - shared_from_this

本文介绍了std::enable_shared_from_this的用法,通过示例对比了正确与错误的使用方式,展示了如何避免双删问题,并提供了lambda表达式中安全地捕获this指针的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

shared_from_this

class只要继承自std::enable_shared_from_this<class>,程序便可以通过shared_from_this获取共享的智能this指针。

使用示例

  • 示例1
    当获取某个类对象的智能指针时,避免出现两个引用计数独立的智能指针同时指向同一个实例,从而出现double free的问题。
#include <memory>
#include <iostream>
 
struct Good: std::enable_shared_from_this<Good> // note: public inheritance
{
    std::shared_ptr<Good> getptr() {
        return shared_from_this();
    }
};
 
struct Bad
{
    std::shared_ptr<Bad> getptr() {
        return std::shared_ptr<Bad>(this);
    }
    ~Bad() { std::cout << "Bad::~Bad() called\n"; }
};
 
int main()
{
    // Good: the two shared_ptr's share the same object
    std::shared_ptr<Good> gp1 = std::make_shared<Good>();
    std::shared_ptr<Good> gp2 = gp1->getptr();
    std::cout << "gp2.use_count() = " << gp2.use_count() << '\n';
 
    // Bad: shared_from_this is called without having std::shared_ptr owning the caller 
    try {
        Good not_so_good;
        std::shared_ptr<Good> gp1 = not_so_good.getptr();
    } catch(std::bad_weak_ptr& e) {
        // undefined behavior (until C++17) and std::bad_weak_ptr thrown (since C++17)
        std::cout << e.what() << '\n';    
    }
 
    // Bad, each shared_ptr thinks it's the only owner of the object
    std::shared_ptr<Bad> bp1 = std::make_shared<Bad>();
    std::shared_ptr<Bad> bp2 = bp1->getptr();
    std::cout << "bp2.use_count() = " << bp2.use_count() << '\n';
} // UB: double-delete of Bad

Possible output:

gp2.use_count() = 2
bad_weak_ptr
bp2.use_count() = 1
Bad::~Bad() called
Bad::~Bad() called
*** glibc detected *** ./test: double free or corruption
  • 示例2
    lambda表达式利用shared_from_this可以安全的捕获this指针
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <algorithm>
#include <functional>
#include <mutex>
#include <thread>
#include <exception>
#include <Windows.h>

using namespace std;

class Foo : public enable_shared_from_this<Foo> 
{
private:
    int a = 11;

public:
    void func()
    {
        auto tmp_shared = shared_from_this();
        // 如果此处捕获的式this指针,程序结果又会如何?
        std::thread([tmp_shared]()
        {
            Sleep(1000);
            cout << "sleep over" << endl;
            cout << "a is " << tmp_shared->a << endl;
        }).detach();
        cout << "func return" << endl;
    }

    Foo() { cout << "in Foo" << endl; }
    ~Foo() { cout << "in ~Foo" << endl; }
};

int main() 
{
    {
        auto a = make_shared<Foo>();
        a->func();
    }
    getchar();
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值