Public boost :: signal object - PullRequest
       17

Public boost :: signal object

4 голосов
/ 14 февраля 2009

Я делаю свои boost::signal открытыми, потому что я ленивый.

class Button {
public:
    signal<void()> clicked;
};

int main() {
    Button btn;
    btn.clicked.connect(handleClick);
}

... вместо инкапсуляции с Button::OnClicked(boost::function<void()>).

Это собирается вернуться и укусить меня?

Ответы [ 4 ]

3 голосов
/ 14 февраля 2009

Это зависит.

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

Кроме того, это может затруднить точное отслеживание того, когда другие объекты подключаются к какому-либо данному объекту.

Я бы сказал, скрыть соединения за функцией, чтобы быть на безопасной стороне.

Обычно я использую макрос для определения ванильной функции.

#define SIGNAL(slot,name) connection name(function<slot> func) { return _##name##.connect(func);}

А затем в определении класса:

SIGNAL(void(),clicked)

Это предполагает, что вы следуете соглашению о присвоении имени сигналу _clicked, но вы можете заменить любое соглашение. Обычно он поддерживает чистоту интерфейса для всех ваших классов. Когда вы хотите добавить специальную логику соединения, вы можете, не изменяя все другие объекты, которые используют сигнал.

EDIT

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

Или когда мне хотелось каждый раз регистрировать что-то, связанное с определенным сигналом. Это было сделано только для целей отладки, но может быть очень полезно, если вы подозреваете, что происходит что-то нехорошее, например циклы в ваших сигнальных соединениях.

2 голосов
/ 12 января 2012

Я наткнулся на вескую причину , а не , чтобы сделать это.

Мы смотрим на использование сторонней библиотеки, которая выставляет сигналы boost :: на внешнем интерфейсе. Эта библиотека зависит от версии boost с набором определений компилятора, которые двоично несовместимы со стандартными определениями компилятора Visual Studio, которые мы используем в нашем проекте. Всякий раз, когда мы пытаемся вызвать signal.connect сторонней библиотеки, вещи умирают.

Решение для нас:

  1. Перекомпилируйте все наши исходные и зависимые библиотеки с предоставленной ими улучшенной версией.
  2. Обернуть сигналы повышения и скрыть реализацию

Что-то рассмотреть, по крайней мере!

0 голосов
/ 20 сентября 2009

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

0 голосов
/ 15 февраля 2009

Ну, этот вопрос на самом деле не имеет ничего общего с boost::signal или function - все дело в инкапсуляции.

Нужен ли клиент класса Button полный доступ к clicked? Если все, что они могут сделать, это подписаться на него, то разрешите только это с помощью метода OnClicked. Разоблачение этого может укусить вас ИМХО.

Как всегда, вы балансируете затраты и выгоды. В этом случае стоимость очень низкая. Если бы вы были в моей команде, я бы настоятельно рекомендовал вам добавить метод OnClicked.

...