На основе За пределами стандартной библиотеки C ++: Введение в Boost , раздел Использование Boost.Bind с Boost.Function на стр. 328, автор иллюстрирует один из способов, которым мыможет отделить вызывающий код от базового кода реализации.
При отделении графических пользовательских интерфейсов (GUI) от подробностей о том, как обрабатывать действия (события) от пользователя, некоторые обратные вызовы почти всегда используются.Если этот механизм обратного вызова основан на указателях функций, трудно избежать серьезных ограничений типов, которые могут использоваться с обратным вызовом, что, в свою очередь, увеличивает риск добавления связи между представлением и бизнес-логикой.Мы можем полностью избежать этого, используя Boost.Function, и в сочетании с библиотекой, которая поддерживает привязку аргументов, мы можем с легкостью предоставлять контекст для вызова функций.Это одно из наиболее распространенных применений этой библиотеки для отделения знаний о бизнес-логике от уровня представления.
class tape_recorder {
public:
void play() {
std::cout << "Since my baby left me...\n";
}
void stop() {
std::cout << "OK, taking a break\n";
}
void forward() {
std::cout << "whizzz\n";
}
void rewind() {
std::cout << "zzzihw\n";
}
void record(const std::string& sound) {
std::cout << "Recorded: " << sound << '\n';
}
};
typedef boost::function<void()> command;
tape_recorder tr;
command play(boost::bind(&tape_recorder::play,&tr));
command stop(boost::bind(&tape_recorder::stop,&tr));
command forward(boost::bind(&tape_recorder::stop,&tr));
command rewind(boost::bind(&tape_recorder::rewind,&tr));
std::string s="What a beautiful morning...";
command record = boost::bind(&tape_recorder::record,&tr,s));
// Invoked from some GUI control...
if (play) {
play.execute();
}
// Invoked from some scripting client...
stop.execute();
С Boost.Function и Boost.Bind можнодобиться развязки, которая позволяет вызывающему коду ничего не знать о вызываемом коде.Таким способом чрезвычайно полезно объединить эти две библиотеки.
Вопрос > Я понимаю, как работает приведенный выше код, но все еще не понимаю, как отделить вызывающий код от реального.реализация как то, что автор изначально хочет архивировать.Код вызова (т. Е. Все виды команд) все еще должен знать, какие функции-члены tape_recorder
.Так что же на самом деле означает разделение?