C++ 中 enable_shared_from_this 的使用总结

本文介绍了C++11中的`enable_shared_from_this`模板类,用于在类内部安全地获取`this`指针的`shared_ptr`版本。通过示例展示了如何避免内存重复释放问题,并探讨了在异步任务中使用`this`指针可能导致的问题及解决方案。通过`enable_shared_from_this`,可以在异步回调中延长对象的生命周期,确保其在异步操作完成前不被提前释放。

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

背景

enable_shared_from_this 是 C++11 定义在头文件 include 中的一个模板类,其作用是在类的内部安全的得到 this 指针的 shared_ptr 版本。

获取 this 的 shared_ptr 版本

①.概述

shared_ptr 是通过引用计数来判断对象是否可以被销毁。

②.通过 this 创建 shared_ptr

多次通过原始指针创建 shared_ptr 不会增加引用计数,且会造成内存重复释放。

class demoClass
{
public:
    demoClass(){ cout << "demoClass 构构" << endl; }
    ~demoClass(){ cout << "demoClass 析构" << endl; }

    void func()
{
        shared_ptr<demoClass> sp(this);
        cout << "当前引用计数 " << sp.use_count() << endl;
    }
};

int main()
{
    demoClass* demo = new demoClass;
    shared_ptr<demoClass> sp(demo);
    cout << "当前引用计数 " << sp.use_count() << endl;
    demo->func();

    system("pause");
    return 0;
}

在这里插入图片描述

③.继承 enable_shared_from_this 实现

class demoClass: public enable_shared_from_this<demoClass>
{
public:
    demoClass(){ cout << "demoClass 构构" << endl; }
    ~demoClass(){ cout << "demoClass 析构" << endl; }

    void func()
{
        shared_ptr<demoClass> sp = shared_from_this();
        cout << "当前引用计数 " << sp.use_count() << endl;
    }
};

int main()
{
    demoClass* demo = new demoClass;
    shared_ptr<demoClass> sp(demo);
    cout << "当前引用计数 " << sp.use_count() << endl;
    demo->func();
 
    return 0;
}

在这里插入图片描述

类的内部异步使用 this 指针

①.概述

使用 std::async 可以开启一个异步任务,返回一个 std::future 对象。需要注意的是 std::future 对象的析构函数会等待异步操作的完成。

②.异步回调中使用 this 指针

若在异步任务执行期间该对象已经被释放,则会出错。

class demoClass 
{
public:
    demoClass(){ cout << __FUNCTION__ << endl; }
    ~demoClass(){ cout << __FUNCTION__ << endl; }
public:
    void func()
{
        cout << __FUNCTION__ << endl;
        this_thread::sleep_for(chrono::seconds(5));
        cout << msg << endl;
    }
    void asyncFunc(future<void> & f )
{
        f = async(launch::async, bind(&demoClass::func, this )); 
        cout << __FUNCTION__ << endl;
    }
private:
    string msg = "hello world";
};

future<void> m_future;//为确保真的异步
int main()
{
    {
        shared_ptr<demoClass> demo(new demoClass);
        demo->asyncFunc(m_future);      
    }//释放 demo
    cout << __FUNCTION__ << endl;
   
    m_future.wait();
   
    return 0;
}

在这里插入图片描述

③.使用 shared_from_this 延长对象生命周期

class demoClass : public enable_shared_from_this<demoClass>
{
public:
    demoClass(){ cout << __FUNCTION__ << endl; }
    ~demoClass(){ cout << __FUNCTION__ << endl; }
public:
    void func()
{
        cout << __FUNCTION__ << endl;
        this_thread::sleep_for(chrono::seconds(5));
        cout << msg << endl;
    }
    void asyncFunc(future<void> & f )
{
        f = async(launch::async, bind(&demoClass::func, shared_from_this() )); 
        cout << __FUNCTION__ << endl;
    }
private:
    string msg = "hello world";
};

future<void> m_future;
int main()
{
    {
        shared_ptr<demoClass> demo(new demoClass);
        demo->asyncFunc(m_future);      
    }
    cout << __FUNCTION__ << endl;
   
    m_future.wait();
   
    return 0;
}

在这里插入图片描述

注意事项

继承自 enable_shared_from_this 类可以安全的得到 this 的 shared_ptr 版本,关键在于其 private 的 weak_ptr 变量 ,因此在使用时必须注意以下两点

①.必须 public 继承自 enable_shared_from_this,只有public 继承才可以继承父类的 private 成员。

②.必须使用 shared_ptr 来管理对象,确保 weak_ptr 变量被初始化。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值