如何制作可复制的boost :: signal?

时间:2009-03-05 19:06:12

标签: c++ boost-signals noncopyable

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

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

首先想到的解决方案是继承signal并在派生类中提供复制ctor,但这是禁止的,因为信号没有虚拟dtor。

思想?

6 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:3)

我会在shared_ptr内部保留信号。这样你的对象就可以直接复制,你可以使用值语义。

答案 2 :(得分:2)

不要派生。这是一个坏主意,它对你没有任何好处 - 你的派生类也不会是可复制的。无论你要暴露哪些信号部分,以及你想要实现的任何行为,都要用你自己的类来做,只需在幕后使用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

答案 3 :(得分:1)

你的信号没有代理对象吗?代理将保持信号和引用计数。不是创建信号的副本,而是与代理进行通信,这反过来会增加/减少计数。这有用吗?

您可能也想参考Decorator模式。

答案 4 :(得分:1)

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

答案 5 :(得分:1)

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

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