2

我想在多线程应用程序中使用带有自动连接管理的 boost signals2。我的类继承自enable_shared_from_this<>,我想从另一个成员方法中连接一个成员方法。连接可能会经常重建,因此我的代码应该尽可能快(尽管提升了信号2性能本身):

typedef boost::signals2::signal<void ()> signal_type;

struct Cat : public enable_shared_from_this<Cat>
{
  void meow ();

  void connect (signal_type& s)
  {
    // can't write this
    s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (weak_from_this ()));

    // ok, but slow?! two temporary smart pointers
    weak_ptr<Cat> const myself (shared_from_this ());
    s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (myself));
  }

  // i am missing something like this in the base class
  // protected:
  //   weak_ptr<Cat> const& weak_from_this ();
};

我知道我的设计目标可能是冲突的(自动连接管理和线程安全以及快速代码),但无论如何:

  1. 为什么enable_shared_from_this<>缺乏对嵌入式的直接访问weak_ptr<>?我看不到相反的理由。没有和我类似的用例吗?

  2. 有比上述更快的解决方法吗?

编辑:

我知道我可以这样做,但我想避免额外的存储/初始化检查惩罚:

template <typename T>
struct enable_weak_from_this : public enable_shared_from_this<T>
{
protected:
  weak_ptr<T> /* const& */ weak_from_this ()
  {
    if (mWeakFromThis.expired ())
    {
      mWeakFromThis = this->shared_from_this ();
    }

    return mWeakFromThis;
  }

private:
  weak_ptr<T> mWeakFromThis;
};
4

2 回答 2

2

您无权访问的原因weak_ptrenable_shared_from_this不必使用 one。拥有 aweak_ptr只是 的一种可能实现enable_shared_from_this。它不是唯一的。

由于enable_shared_from_this是与 相同的标准库的一部分,shared_ptr因此可以使用比直接存储weak_ptr. 委员会不想阻止这种优化。

// 好的,但是慢?!两个临时智能指针

这只是一个临时智能指针。复制省略/移动应该处理除第一个对象之外的任何内容。

于 2013-04-10T15:13:04.367 回答
-1

这可能是因为没有shared_ptr引用该Cat实例。weak_ptr要求至少有一个 active shared_ptr

尝试放置一个shared_ptr作为成员变量并在connect方法中首先分配给它:

typedef boost::signals2::signal<void ()> signal_type;

struct Cat : public enable_shared_from_this<Cat>
{
  void meow ();
  boost::shared_ptr<Cat> test;

  void connect (signal_type& s)
  {
    test = shared_from_this();
    s.connect (signal_type::slot_type (&Cat::meow, this, _1).track (weak_from_this ()));
  }
};

但基本上,weak_ptr如果没有,就不可能有shared_ptr。如果在仍在使用时全部shared_ptr消失,则可能指向不存在的对象。weak_ptrweak_ptr

注意:我的测试不应该在生产代码中使用,因为它会导致对象永远不会被释放。

于 2013-04-10T15:00:58.170 回答