c++ std::enable_shared_from_this作用

enable_shared_from_this 是什么

std::enable_shared_from_this 是一个类模板,用来返回指向当前对象的shared_ptr智能指针。在说明它的作用前我们可以看一下如下代码:

demo.cpp

#include <memory>
#include <iostream>
     
class A
{
public:
    A() { std::cout << "A()" << std::endl; }
    ~A() { std::cout << "~A()" << std::endl; }

    std::shared_ptr<A> getSharedPtr()
    {
        std::shared_ptr<A> ptr(this);
         return ptr;
    }
};
     
int main()
{
    std::shared_ptr<A> ptr1(new A());
    std::shared_ptr<A> ptr2 = ptr1->getSharedPtr();
     
    return 0;
}

类 A 中有一个函数 getSharedPtr() 函数,用来返回指向当前对象的一个shared智能打针。其实就是用 this 构造了一个智能指针进行返回,执行结果如下:
在这里插入图片描述
看着好像没什么问题,别着急,再看下一个例子:

class B
{
public:
    B() { 
        m_age = new int(10);
        std::cout << "B()" << std::endl; 
        
    }
    ~B() { 
        std::cout << "~B()" << std::endl; 
        if (m_age){
            delete m_age;
            m_age = nullptr;
        }
    }

    std::shared_ptr<B> getSharedPtr()
    {
        std::shared_ptr<B> ptr(this);
         return ptr;
    }
private:
    int* m_age;
};

int main()
{
    std::shared_ptr<B> ptr1(new B());
    std::shared_ptr<B> ptr2 = ptr1->getSharedPtr();
     
    std::cout << ptr1.use_count() << std::endl; // 输出引用计数
    std::cout << ptr2.use_count() << std::endl; // 输出引用计数
    return 0;
}

与类A不同的是,类B有一个在堆上创建的成员,我们再来看一下运行结果:
在这里插入图片描述
可以看到程序再运行到最后时刻崩溃了,报错:free(): invalid pointer,free 了无效的指针。我们应该能看到是重复释放的问题,这里我们将裸指针赋给了智能指针,这样做潜在的危险就是对象被多次释放。

细心的小伙伴肯定看到了,智能指针ptr1 和 ptr2 的引用计数都是 1,在程序执行结束的时候都会释放一次资源,导致程序崩溃。enable_shread_from_this 的作用就是解决这个问题,示例代码如下:

class C: public std::enable_shared_from_this<C>
{
public:
    C() { 
        m_age = new int(10);
        std::cout << "C()" << std::endl; 
        
    }
    ~C() { 
        std::cout << "~C()" << std::endl; 
        if (m_age){
            delete m_age;
            m_age = nullptr;
        }
    }

    std::shared_ptr<C> getSharedPtr()
    {
        return shared_from_this();
    }
private:
    int* m_age;
};

int main()
{
    std::shared_ptr<C> ptr1(new C());
    std::shared_ptr<C> ptr2 = ptr1->getSharedPtr();
     
    std::cout << ptr1.use_count() << std::endl;
    std::cout << ptr2.use_count() << std::endl;
    return 0;
}

运行结果如下:
在这里插入图片描述

可以看到,此时两个智能指针的引用计数都为2,这两个智能指针指向了相同的资源。在 main 函数退出后,两个智能指针依次释放,引用计数依次减一,直至为0,资源成功释放。

推荐一个零声学院免费教程,个人觉得老师讲得不错,
分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值