Как сделать копируемый boost::signal?
Я понимаю почему boost::signal
не копируемый (это потому, что копирование сигнала не имеет ясного смысла), но мне нужна его версия, которая предоставляет некоторый вид ctor для копирования (либо неоперативный, либо тот, который копирует все соединения).
Причина, по которой мне это нужно, заключается в том, что в моем проекте многие объекты становятся не копируемыми только благодаря отображению сигналов, и для обработки их с помощью удобной семантики значений (shared_ptrs не так удобны), мне нужно вручную предоставить копировальные-разделители, нарушающие DRY. Очевидно, что своего рода квази-копируемый сигнал будет хорошим обходным путем для уродства C++.
Первое решение, которое приходит на ум, это наследование signal
и предоставление копии ctor в производном классе, но это не нужно, потому что у сигнала нет виртуального dtor.
Мысли?
6 ответов
Попробуйте удерживать указатели (или shared_ptr) на синглах вместо сигналов.
Я бы пошел для хранения сигналов внутри в shared_ptr. Таким образом, ваши объекты будут напрямую копироваться, и вы можете использовать семантику значений.
Не извлекай. Это плохая идея, и она не принесет вам никакой пользы - ваш производный класс также не будет копироваться. Независимо от того, какие части сигнала вы хотите раскрыть, и какое бы поведение вы ни хотели реализовать, сделайте это с вашим собственным классом и просто используйте 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
Разве у вас нет прокси-объекта для ваших сигналов? Прокси будет поддерживать как сигнал, так и счетчик ссылок. Вместо того, чтобы создавать копии сигналов, поговорите с прокси, который, в свою очередь, увеличит / уменьшит счет. Это работает?
Вы можете также обратиться к шаблону Decorator.
Внутреннее удержание сигнала в shared_ptr (по умолчанию) приведет к тому, что сигнал будет использоваться всеми скопированными объектами. Запуск сигнала в одном объекте приведет к тому, что каждый слот, связанный с сигналом на всех копиях, будет уведомлен. Это может быть не то поведение, которое вы хотите.
Если вы не хотите, чтобы это произошло, вы можете написать свой собственный конструктор копирования и оператор присваивания копии, тогда вы сможете указать, что вы хотите, чтобы происходило при копировании ваших объектов.
Определенно вы можете использовать boost:: ref. Это основная цель этого класса. Он также использовался в предыдущих версиях boost, когда потоки не могли быть скопированы. Единственным недостатком является то, что сигналы могут управляться вне класса, поэтому ссылки, сохраненные во всех скопированных классах, всегда действительны.