Мне нужно создать простой обратный вызов на c ++?Должен ли я использовать функцию boost::?
Вопрос
Предположим, у меня есть какой-то подобный код:
class Visitor {
public:
Visitor(callBackFunction) {}
void visit() {
//do something useful
invokeCallback();
}
}
class ClassThatCanBeVisited {
Visitor &visitor;
public:
ClassThatCanBeVisited(Visitor &_visitor) : visitor(_visitor){}
void someUsefulMethod() {
int data= 42;
visitor.visit(data);
}
};
void callBackFunction() {
//do something useful in the context of the Main file
}
int main() {
Visitor visitor;
ClassThatCanBeVisited foo(visitor);
foo.someUsefulMethod();
}
Мне нужно создать простой обратный вызов, который будет вызываться всякий раз, когда вызывается Visitor::visit().Я знаю, что мне, вероятно, следует поместить код обратного вызова внутрь моего Посетителя, но это в другом контексте, поэтому я хотел бы передать CallbackFunction() Посетителю, чтобы он мог вызвать мою функцию обратного вызова.
Я поискал что-нибудь в Интернете и увидел boost::function, но в c ++ уже есть базовые функторы.
Какой из них мне следует использовать для большей ясности кода?Обратный вызов будет простой функцией void (), но она может вырасти, вы никогда не знаете будущего :)
Каков рекомендуемый способ сделать это?
Решение
Вы можете использовать интерфейс обратного вызова и его иерархию, если вы не хотите использовать boost::function.
class VisitorCallback
{
public:
virtual void handle( const Visitor& ) = 0;
};
Если у вас есть или вы можете использовать boost::function - используйте его, это хороший способ избавиться от всех этих классов обратного вызова.
Редактировать:
@edisongustavo:
boost::function и boost::bind, вероятно, не сделают ваш код более читабельным.Но это даст вам возможность передавать свободные функции (я имею в виду функции вне класса и статические функции класса) в качестве обратного вызова, а также существующие функции любого класса.
С помощью функций boost вы можете передавать функции, например, с 2 параметрами, в качестве обратного вызова, которые ожидают только один параметр.
typedef boost::function< void ( int ) > IntExpectingCallback;
void TwoIntFunction( int, int );
{
}
...
IntExpectingCallback callback = boost::bind( TwoIntFunction, 5, _1 );
Но опять же, это не сделает ваш код более читабельным, если вся ваша команда не будет знать и поддерживать boost.
Другие советы
Да, функция boost:: сделала бы это хорошо.Это очень распространенное его использование.Вам нужно будет использовать boost::bind, чтобы привязать экземпляр к функции-члену.
func = boost::bind( &MyClass::CallbackFunc, this);
Было бы так, как вы сделали бы это изнутри класса.
Убедитесь, что "это" не исчезнет, иначе ваша функция boost завершит работу в середине какого-нибудь заголовка boost где-нибудь.
Приведенные выше ответы великолепны, но я просто хотел бы указать на то, что вы упомянули в своем вопросе, и которое по-прежнему имеет отношение к вашему выбору между объектами обратного вызова C ++ (в ответе Миколы) и boost.
" обратный вызов будет простой функцией void (), но он может расти, вы никогда не узнаете будущее :)) "
Это, вероятно, наихудшая причина для лишней, ненужной функциональности, то есть «на тот случай, если она вам понадобится». Если вы не знаете - тогда не делайте больше, чем необходимо, скорее всего, ваше предположение будет неверным, особенно к тому времени, когда оно вам понадобится.
С другой стороны, если вы знаете, что весьма вероятно, что вам понадобится функциональность очень скоро , то, возможно, стоит добавить ее.
Еще раз, чтобы повторить то, что сказал Николай - если у вас уже есть повышение в вашем проекте, и вашей команде это нравится, то используйте это, но в противном случае это может быть излишним.