2016-03-08 124 views
0

我需要帮助了解enable_shared_from_this。我对使用enable_shared_from_this感到困惑。 放在一个正确的方法,让我们考虑一个例子,从http://en.cppreference.com/w/cpp/memory/enable_shared_from_this混淆关于enable_shared_from_this

#include <memory> 
#include <iostream> 

struct Good: std::enable_shared_from_this<Good> 
{ 
    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(new Good); 
    std::shared_ptr<Good> gp2 = gp1->getptr(); 
    std::cout << "gp2.use_count() = " << gp2.use_count() << '\n'; 

    // Bad, each shared_ptr thinks it's the only owner of the object 
    std::shared_ptr<Bad> bp1(new Bad); 
    std::shared_ptr<Bad> bp2 = bp1->getptr(); 
    std::cout << "bp2.use_count() = " << bp2.use_count() << '\n'; 
} // UB: double-delete of Bad 

复制在上面的例子

  • 我们呼吁getptr()gp1这是一个shared_ptr
std::shared_ptr<Good> gp2 = gp1->getptr(); 
  • 我认为我们可以做到同样的事情,如果我们做
std::shared_ptr<Good> gp2 = gp1; 
  • 还有就是我发现是有限制的,我们不能调用getpt r()来自 正常对象。它必须是一个shared_ptr。

例:

Good gp; gp.getptr(); // throws std::bad_weak_ptr 
Good *gp1 = new Good(); gp1->getptr();// throws std::bad_weak_ptr 

我的疑问是,当我们已经有了shared_ptr,那么我们也可以直接分配给另一个shared_ptr。如std::shared_ptr<Good> gp2 = gp1;

那么enable_shared_from_this需要什么?

+3

对于需要'T&'(而不是'shared_ptr ')的函数,然后检索'shared_ptr'。 – Jarod42

+0

谢谢@ Jarod42,我明白你的观点。当我们在一个引用变量中有对象时,那么我们就可以得到一个'shared_ptr',这可以通过使用'enable_shared_ptr'来实现。非常感谢 。 – rajenpandit

+0

使用enabled_shared_from_this不是一个好的设计选择。基本上,班级不应该关注自己的管理。在一个好的设计类中可以以多种形式存在 - 它可以由一个共享指针,一个唯一指针,一个原始指针以及自动实例来管理。 – SergeyA

回答

0

shared_from_this()的更常见用法是将调用类的shared_ptr提供给被调用的函数。因此,如果您需要为函数提供shared_ptr实例,并且您确定从中调用的类存储为shared_ptr,则可以使用shared_from_this()。根据您提到的一个伪代码示例:

struct Good: std::enable_shared_from_this<Good> 
{ 
    std::shared_ptr<Good> call_function() { 
     Foo foo; 
     foo.use_my_shared_ptr(shared_from_this()); 
    } 
}; 

Foo这里只是需要一个shared_ptr来Good类。