![]() |
![]() ![]() ![]() ![]() ![]() |
![]() |
Design RationaleBoost , The Boost C++ Libraries BoostBook Documentation Subset , Chapter 33. Boost.Signals2
|
Тянуть |
Толкать |
---|---|
struct pull_max { typedef int result_type; template<typename InputIterator> result_type operator()(InputIterator first, InputIterator last) { if (first == last) throw std::runtime_error("Empty!"); int max_value = *first++; while(first != last && *first <= 100) { if (*first > max_value) max_value = *first; ++first; } return max_value; } }; |
struct push_max { typedef int result_type; push_max() : max_value(), got_first(false) {} // returns false when we want to stop bool operator()(int result) { if (result > 100) return false; if (!got_first) { got_first = true; max_value = result; return true; } if (result > max_value) max_value = result; return true; } int get_value() const { if (!got_first) throw std::runtime_error("Empty!"); return max_value; } private: int max_value; bool got_first; }; |
В этих примерах следует отметить несколько моментов. Версия «pull» является многоразовым функциональным объектом, который основан на последовательности итератора ввода с целым числом value_type
и очень прост в дизайне. Модель «push», с другой стороны, опирается на интерфейс, специфичный для абонента, и обычно не используется повторно. Это также требует дополнительных значений состояния, чтобы определить, например, были ли получены какие-либо элементы. Хотя качество кода и простота использования, как правило, субъективны, модель «вытягивания» явно короче и более многоразовая и часто будет рассматриваться как более простая в написании и понимании, даже вне контекста библиотеки сигналов и усилителей.
Стоимость интерфейса комбинатора «pull» оплачивается при реализации самой библиотеки Signals2. Чтобы правильно обрабатывать отключения слотов во время вызовов (например, когда вызывается оператор отсчета), необходимо построить итератор, чтобы пропустить отключенные слоты. Кроме того, итератор должен нести с собой набор аргументов для передачи в каждый слот (хотя достаточно ссылки на структуру, содержащую эти аргументы), и должен кэшировать результат вызова слота, чтобы множественные ссылки не приводили к нескольким вызовам. Это, по-видимому, требует большой степени накладных расходов, хотя, если рассматривать весь процесс вызова слотов, можно увидеть, что накладные расходы почти эквивалентны таковым в модели «толчка», но мы перевернули структуры управления, чтобы сделать комплекс итерации и отсчета (вместо того, чтобы делать комбинаторный комплекс определения состояния).
Boost.Signals2 поддерживает синтаксис соединения с формой sig.connect(slot)
, но предложен более строгий синтаксис sig += slot
(и использовался другими сигналами & реализациями слотов). Существует несколько причин, по которым этот синтаксис был отклонен:
Необязательно: синтаксис соединения, предоставляемый Boost. Сигналы2 не менее мощны, чем сигналы, подаваемые оператором +=
. Экономия при наборе текста (connect()
против +=
) по существу незначительна. Кроме того, можно утверждать, что вызов connect()
более читаем, чем перегрузка +=
.
Двусмысленный тип возврата : существует двусмысленность относительно значения возврата операции +=
: должна ли она быть ссылкой на сам сигнал, чтобы включить sig += slot1 += slot2
, или должна ли она возвращать signals2::connection
для вновь созданного соединения сигнал/слот?
Переход к операторам -=, +: при добавлении оператора соединения +=
кажется естественным наличие оператора отключения -=
. Однако это создает проблемы, когда библиотека позволяет произвольным функциональным объектам неявно становиться слотами, потому что слоты больше не сопоставимы.
Вторым очевидным дополнением, когда у вас есть оператор +=
, будет добавление оператора +
, который поддерживает добавление нескольких слотов с последующим назначением сигнала. Однако для этого потребуется реализовать +
так, чтобы он мог принимать любые два функциональных объекта, что технически невозможно.
Библиотека Boost.Signals2 предоставляет 2 класса mutex: boost::signals2::mutex
и boost::signals2::dummy_mutex
. Мотивация для предоставления boost::signals2::mutex
заключается просто в том, что класс boost::mutex
предоставлен Boost. В настоящее время библиотека Thread требует ссылки на libboost_thread. Класс boost::signals2::mutex
позволяет Signals2 оставаться библиотекой только для заголовков. При желании вы можете использовать boost::mutex
, указав его в качестве шаблона Mutex
для ваших сигналов.
Класс boost::signals2::dummy_mutex
позволяет чувствительным к производительности однопоточным приложениям минимизировать накладные расходы, избегая ненужной блокировки mutex.
libsigc++ представляет собой C++-сигналы и усилитель; библиотека слотов, которая первоначально начиналась как часть инициативы по обертыванию интерфейсов C в библиотеки GTK на C++ и выросла в отдельную библиотеку, поддерживаемую Карлом Нельсоном. Существует много сходств между libsigc++ и Boost.Signals2. Сигналы находились под сильным влиянием Карла Нельсона и libsigc++. Беглый осмотр каждой библиотеки позволит найти похожий синтаксис для построения сигналов и использования соединений. Существуют некоторые различия в дизайне, которые разделяют эти библиотеки:
Определения слотов: слоты в libsigc++ создаются с использованием набора примитивов, определенных библиотекой. Эти примитивы допускают связывание объектов (как части библиотеки), явную адаптацию от аргумента и типов возврата сигнала к аргументу и типам возврата слота (libsigc++ по умолчанию более строг в отношении типов, чем Boost.Signals2).
Интерфейс комбинатора/маршаллера: эквивалент Boost. Комбинаторами Signals2 в libsigc++ являются маршалы. Маршаллеры похожи на интерфейс «push», описанный в Combiner Interface, и там дается правильная трактовка темы.
Microsoft ввела . NET Framework и связанный с ним набор языков и языковых расширений, одним из которых является делегат. Делегаты похожи на сигналы и слоты, но они более ограничены, чем большинство сигналов C++ и слотов в том, что они:
Требуется точное соответствие типа между делегатом и тем, что он называет.
Возврат только результата последней цели без возможности настройки.
Можно назвать метод с , что
уже связано.
Последние изменения: 12 июня 2007 года в 14:01:23 -0400 |
Статья Design Rationale раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 33. Boost.Signals2 может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: Chapter 33. Boost.Signals2 ::
реклама |