шаблоны проектирования — делегаты с несколькими уведомлениями в переполнении стека

Я рассматривал лучший способ реализации делегатов в C ++, и до сих пор я склонен использовать std::function Обратные вызовы. Однако некоторые из моих классов выдают несколько уведомлений делегатов (например, opened, closed, а также changed_state). Экземпляры, заинтересованные в получении уведомлений делегата, должны назначить один из своих собственных методов (тот факт, что он может быть закрытым — плюс) событию, которое он заинтересован в прослушивании. Однако следует ожидать, что когда какой-либо экземпляр подписывается на любого из делегатов, он подписывается на всех из них. Это означает, что этого события не произойдет Foo выдается одному экземпляру, а событие Bar выдан другому. Есть ли способ, которым я мог бы обеспечить это условие? Ни в коем случае не следует присваивать обратные вызовы различным экземплярам (предполагать атомарность).

Я знаю, что мог бы рассмотреть возможность использования единственного обратного вызова с кодами вызова или чем-то еще, но в этом случае это не вариант (по нескольким причинам, одна из которых заключается в том, что это повлечет за собой необоснованное количество рефакторинга на данном этапе).

Примечание: я знаю, что это другие обсуждения на тему делегатов C ++, но обычно они рассматривают один тип события, а не несколько.

Пример того, что я рассматриваю:

class Connector
{
public:

typedef struct
{
std::function<void()> opened;
std::function<void()> closed;
std::function<void()> changed_state;
} Delegate;

Delegate delegate;
};

// Somewhere else
Connector c;
Listener l;

// This should not be manual. Ideally: c.delegate = l;
c.delegate.opened = l.handle_opened;
c.delegate.closed = l.handle_closed;
c.delegate.changed_state = l.handle_changed_state;

0

Решение

добавлять operator= для этого:

class Connector
{
public:
struct Delegate
{
Delegate& operator = (const Listener& l)
{
opened = l.handle_opened;
closed = l.handle_closed;
changed_state = l.handle_changed_state;
return *this;
}

std::function<void()> opened;
std::function<void()> closed;
std::function<void()> changed_state;
};

Delegate delegate;
};

и тогда вы можете иметь свой синтаксис:

c.delegate = l;
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]