Программирование. Принципы и практика использования C++ Исправленное издание, стр. 216
{ reference_to<Lines_window>(pw).next();}Функция
next()Open_polylinevoid Lines_window::next(){ int x = next_x.get_int(); int y = next_y.get_int(); lines.add(Point(x,y)); // обновляем текущую позицию считывания: ostringstream ss; ss << '(' << x << ',' << y << ')'; xy_out.put(ss.str()); redraw();}Все это совершенно очевидно. Функция
get_int()In_boxostringstreamOut_boxstr()ostringstreamredraw()redraw()WindowА что нового в этой программе? Посмотрим на ее функцию
main()#include "GUI.h"int main()try { Lines_window win(Point(100,100),600,400,"lines"); return gui_main();}catch(exception& e) { cerr << "Исключение: " << e.what() << '\n'; return 1;}catch (...) { cerr << "Какое-то исключение\n"; return 2;}Так ведь здесь, по существу, ничего нет! Тело функции
main()wingui_main()ifswitchgui_main()run()run()while(wait());За исключением некоторых деталей реализации, описание которых вынесено в приложение Д, мы просмотрели весь код, запускающий программу рисования линий. Мы увидели всю логику этой программы. Что же произошло?
16.6. Инверсия управления
А произошло вот что: мы передали поток управления от самой программы элементам управления окном: теперь программа возобновляет свою работу каждый раз, когда активизируется какой-нибудь из этих элементов. Например, щелкните на кнопке, и программа начнет работать. После возврата обратного вызова программа “отключается”, ожидая, пока пользователь сделает что-нибудь еще. По существу, функция
wait()wait()wait()Обычная программа организована следующим образом:

Программа графического пользовательского интерфейса организована иначе.

Как взаимодействуют части программы, активизированные разными обратными вызовами? Проще всего, чтобы функции оперировали данными, хранящимися в окне, как показано в примере из раздела 16.5. В нем функция
next()Lines_windowIn_boxnext_xnext_ylinesOut_box (xy_out)