C++11 New Feature(std::enable_shared_from_this)

我们创建了一个类的对象,同时让std::shared_ptr来管理这个对象,如果此时我们需要传递该对象给其他地方使用时,我们也需要使用std::shared_ptr来传递这个对象.
这里有一小段代码

class c_A {
public:
    ~c_A() {
        std::cout << "c_A destructor\n";
    }
};

int main_c_A() {
    c_A* c_a = new c_A();
    std::shared_ptr<c_A> sharedPtr_c_a(c_a);
    std::shared_ptr<c_A> sharedPtr_c_a2(c_a);

    std::cout << "sharedPtr_c_a : " << sharedPtr_c_a.use_count() << "\n";
    std::cout << "sharedPtr_c_a2 : " << sharedPtr_c_a2.use_count() << "\n";

    return 0;
}

这段代码的运行结果很容易知道.

sharedPtr_c_a : 1
sharedPtr_c_a2 : 1
c_A destructor
c_A destructor

运行结果是崩了,毕竟一个类被析构了两次.两个shared_ptr彼此独立,虽然都指向c_a,但是自己的引用计数都是1

正常应该是

std::shared_ptr<c_A> sharedPtr_c_a2 = sharedPtr_c_a;

这样就可以彼此有点关联,引用计数不再是1,而是2.

如果有这么一个类, 当类对象被share_ptr管理,且在类的成员函数里需要把当前类对象作为参数传给其他函数时,就需要传递一个指向自身的share_ptr.

class c_C : public std::enable_shared_from_this<c_C> {
public:
    std::shared_ptr<c_C> getSharedPtr() {
        return std::shared_ptr<c_C>(this);
    }
    ~c_C() {
        std::cout << "c_C destructor\n";
    }
};

int main_c_C() {
    c_C* c_c = new c_C();
    std::shared_ptr<c_C> sharedPtr_c_c(c_c);
    std::shared_ptr<c_C> sharedPtr_c_c2 = sharedPtr_c_c->getSharedPtr();

    //std::shared_ptr<c_C> sharedPtr_c_b2 = sharedPtr_c_b;

    std::cout << "sharedPtr_c_c : " << sharedPtr_c_c.use_count() << "\n";
    std::cout << "sharedPtr_c_c2 : " << sharedPtr_c_c2.use_count() << "\n";
    return 0;
}

这种情况就类似第一部分的代码一样的情况,因为传递的shared_ptr自己维持新的引用,这样的运行结果

sharedPtr_c_c : 1
sharedPtr_c_c2 : 1
c_C destructor
c_C destructor

也是崩了.

所以可以利用C++11的新特性 enable_shared_from_this.
cplusplus.com解释

  1. 基类如果是std::enable_shared_from_this, 那派生类T可以使用shared_from_this成员函数.
  2. 这个成员函数的作用就是可以让派生类对象创建一个指向自己的shared_ptr实例,而且就算是已经存在了其他shared_ptr对象,同样会共享所有权,而不是创建不同的所有权分组.
class c_B : public std::enable_shared_from_this<c_B> {
public:
    std::shared_ptr<c_B> getSharedPtr() {
        return shared_from_this();
    }
    ~c_B() {
        std::cout << "c_B destructor\n";
    }
};

int main_c_B() {
    c_B* c_b = new c_B();
    std::shared_ptr<c_B> sharedPtr_c_b(c_b);
    //std::shared_ptr<c_B> sharedPtr_c_b2 = c_b->getSharedPtr();

    std::shared_ptr<c_B> sharedPtr_c_b2 = sharedPtr_c_b;

    std::cout << "sharedPtr_c_b : " << sharedPtr_c_b.use_count() << "\n";
    std::cout << "sharedPtr_c_b2 : " << sharedPtr_c_b2.use_count() << "\n";
    return 0;
}

sharedPtr_c_b : 2
sharedPtr_c_b2 : 2
Hello, World!
c_B destructor

Process finished with exit code 0

程序运行,成功退出,不崩溃了
这里有一句"注意,简单地返回shared_ptr(this)会有问题,因为这会创建一个不同的所有权组."

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值