【问题标题】:How to make a copyable boost::signal?如何制作可复制的 boost::signal?
【发布时间】:2010-10-11 14:20:29
【问题描述】:

我明白为什么 boost::signal 是不可复制的(这是因为复制信号没有明确的含义),但我需要一个确实提供 一些 类型的复制 ctor 的版本(或者无操作或复制所有连接的操作)。

我需要这个的原因是因为在我的项目中,许多对象变得不可复制仅仅凭借特征信号,并且用舒适的值语义来对待它们(shared_ptrs 不是一样舒服)我需要手动提供复制操作符,这违反了 DRY。显然,一种准可复制的信号将是解决 C++ 丑陋的一个很好的解决方法。

想到的第一个解决方案是继承 signal 并在派生类中提供一个复制 ctor,但这是不行的,因为 signal 没有虚拟 dtor。

想法?

【问题讨论】:

  • 复制信号的问题是任何和所有connection 对象都将引用旧信号。请记住这一点!

标签: c++ boost-signals noncopyable


【解决方案1】:

尝试在信号上保持指针(或 shared_ptr )而不是信号。

【讨论】:

    【解决方案2】:

    我会在 shared_ptr 内部保存信号。这样,您的对象将直接可复制,并且您可以使用值语义。

    【讨论】:

      【解决方案3】:

      不要派生。这是个坏主意,而且对你没有任何好处——你的派生类也不能复制。无论您想要公开信号的任何部分,以及您想要实现的任何行为,都可以使用您自己的类来完成,并且只需在幕后使用 boost::signal。

      namespace Iraimbilanja {
      
      // the copy constructor doesn't copy the signal, so it doesn't copy the connections...
      struct EmptyOnCopySignal
      {
      private:
          boost::shared_ptr<boost::signal> _signal;
      };
      
      // the copy constructor references the same signal, so it copies the connections...
      struct CopyableSignal
      {
      private:
          boost::shared_ptr<boost::signal> _signal;
      };
      
      } // namespace Iraimbilanja
      

      【讨论】:

        【解决方案4】:

        你的信号不能有代理对象吗?代理将同时维护信号和引用计数。与其创建信号副本,不如与代理交谈,代理将依次增加/减少计数。这行得通吗?

        您可能还想参考Decorator 模式。

        【讨论】:

        • 这很好,但我如何将适当数量的 args 转发给 signalN::operator()()?
        • 将策略对象传递给代理,代理将转发合适的对象(如果有)。
        • 嗯什么策略对象?比如,一个专门针对 10 个参数的转发器,并在信号调用站点为所需的 argcount 实例化?
        • en.wikipedia.org/wiki/Policy-based_design不要拿那个模式的字母,而是它的单词。
        【解决方案5】:

        你当然可以使用boost::ref。这是这个类的主要目的。当线程无法复制时,它也用于以前版本的 boost。唯一的缺点是信号可能在类之外进行管理,因此存储在所有复制的类上的引用始终有效。

        【讨论】:

          【解决方案6】:

          在 shared_ptr 内部保存信号将(默认情况下)导致信号被所有复制的对象共享。在一个对象中触发信号将导致通知所有副本上连接到信号的每个插槽。这可能不是您想要的行为。

          如果您不希望这种情况发生,您可以编写自己的复制构造函数和复制赋值运算符,然后您将能够指定复制对象时想要发生的情况。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-08-22
            • 1970-01-01
            • 2019-02-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多