shared_from_this和私有继承

时间:2016-10-13 11:48:59

标签: c++ visual-studio-2015

cpp reference有关于如何使用std::enable_shared_from_this(略微调整)

的示例
class Good : std::enable_shared_from_this<Good>
{
    public: std::shared_ptr<Good> getptr() { return shared_from_this(); }
};

...

auto good = std::make_shared<Good>();
good->getptr();

但是,这在Visual Studio 2015(Enterprise,版本14.0.25123.00 Update 2)中不起作用,即抛出std::bad_weak_ptr异常。

查看其他示例(包括cpp referenceMicrosoft中的不同示例),我注意到他们使用public继承而不是private。使用public继承实际上解决了我的问题(不再是std::bad_weak_ptr而是有效的shared_ptr)。

Cpp引用没有提到我必须公开继承std::enable_shared_from_this,那么错误在哪里? Visual Studio的行为是错误的(我猜在使用private继承时存在可见性问题)或者cpp引用是否未提及此限制?

PS:make_shared<good>()shared_ptr<Good>(new Good)没有任何区别。

PSS:两个版本都编译得很好,私有版本无法正常工作,这使得它成为一个非常讨厌的bug。

编辑:将struct更改为class。 Cpp引用实际上在其示例中使用了 public 继承。 尽管如此,还没有任何消息说它必须公开。它实际上是在那里列出的,我只需要学会仔细阅读。谢谢@Angew。

2 个答案:

答案 0 :(得分:3)

std::enable_shared_from_this的典型实现,要求std::shared_ptr构造函数(在您的情况下由std::make_shared调用)才能检测到std::enable_shared_from_this库的存在,所以它可以设置该基数的std::weak_ptr成员。

使用私有继承,这是不可能的,因此您获得调用shared_from_this时获得的运行时异常(因为std::weak_ptr从未设置,因为std::shared_ptr构造函数无法检测到std::enable_shared_from_this基数。

C ++标准提到了这样的实现:

  

[注意:可能的实现如下所示:

template<class T> class enable_shared_from_this {
private:
  weak_ptr<T> __weak_this;
protected:
  constexpr enable_shared_from_this() : __weak_this() { }
  enable_shared_from_this(enable_shared_from_this const &) { }
  enable_shared_from_this& operator=(enable_shared_from_this const &) { return *this; }
  ~enable_shared_from_this() { }
public:
  shared_ptr<T> shared_from_this() { return shared_ptr<T>(__weak_this); }
  shared_ptr<T const> shared_from_this() const { return shared_ptr<T const>(__weak_this); }
};
     

创建唯一指针的shared_ptr构造函数可以检测enable_shared_from_this库的存在,并将新创建的shared_ptr分配给其__weak_this成员。 - 结束说明]

您链接的cppreference page也会在备注中提到这一点。

答案 1 :(得分:1)

您问题中的代码根本不使用私有继承:struct默认为公共访问控制,包括成员和基类。

此外,cppreference不会遗漏任何内容。该页面的文字明确指出:

  

公开继承自std::enable_shared_from_this<T> ...

(强调我的)