Как сделать копируемый boost :: signal? - PullRequest
3 голосов
/ 05 марта 2009

Я понимаю, почему boost::signal нельзя скопировать (это потому, что копирование сигнала не имеет четкого значения), но мне нужна его версия, которая обеспечивает некоторый вид копирования ctor (либо no-op или тот, который копирует все соединения).

Причина, по которой я нуждаюсь в этом, заключается в том, что в моем проекте многие объекты становятся некопируемыми просто благодаря отображению сигналов и для обработки их с удобной семантикой значений (shared_ptrs не как удобные ) Мне нужно вручную предоставить копи-ctors, нарушающие DRY. Очевидно, что своего рода квази-копируемый сигнал был бы хорошим обходным путем для уродства C ++ здесь.

Первое решение, которое приходит на ум, - это наследовать signal и предоставлять копию ctor в производном классе, но это не так, потому что у сигнала нет виртуального dtor.

Мысли

Ответы [ 6 ]

7 голосов
/ 05 марта 2009

Попробуйте указатели (или shared_ptr) на синглах вместо сигналов.

3 голосов
/ 05 марта 2009

Я бы пошел для хранения сигналов внутри в shared_ptr. Таким образом, ваши объекты будут напрямую копироваться, и вы можете использовать семантику значений.

2 голосов
/ 05 марта 2009

Не извлекай. Это плохая идея, и она не принесет вам никакой пользы - ваш производный класс также не будет копируемым. Независимо от того, какие части сигнала вы хотите раскрыть, и какое бы поведение вы ни хотели реализовать, сделайте это с вашим собственным классом и просто используйте 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
1 голос
/ 21 марта 2012

Внутреннее удержание сигнала в shared_ptr (по умолчанию) приведет к тому, что сигнал будет использоваться всеми скопированными объектами. Запуск сигнала в одном объекте приведет к тому, что каждый слот, связанный с сигналом на всех копиях, будет уведомлен. Это может быть не то поведение, которое вы хотите.

Если вы не хотите, чтобы это произошло, вы можете написать свой собственный конструктор копирования и оператор присваивания копии, тогда вы сможете указать, что вы хотите, чтобы происходило при копировании ваших объектов.

1 голос
/ 06 марта 2009

Определенно вы можете использовать boost :: ref . Это основная цель этого класса. Он также использовался в предыдущих версиях boost, когда потоки не могли быть скопированы. Единственным недостатком является то, что сигналы могут управляться вне класса, поэтому ссылки, сохраненные во всех скопированных классах, всегда действительны.

1 голос
/ 05 марта 2009

Разве у вас нет прокси-объекта для ваших сигналов? Прокси будет поддерживать как сигнал, так и счетчик ссылок. Вместо того, чтобы создавать копии сигналов, поговорите с прокси, который, в свою очередь, увеличит / уменьшит количество. Это работает?

Вы также можете обратиться к шаблону Декоратор .

...