Язык программирования C++ для профессионалов



         

Указатель на функцию - часть 2


typedef void (*PF)();

PF edit_ops[] = { // команды редактора &cut, &paste, &snarf, &search };

PF file_ops[] = { // управление файлом &open, &reshape, &close, &write

};

Далее надо определить и инициализировать указатели, с помощью которых будут запускаться функции, реализующие выбранные из меню команды. Выбор происходит нажатием клавиши мыши:

PF* button2 = edit_ops; PF* button3 = file_ops;

Для настоящей программы редактора надо определить большее число объектов, чтобы описать каждую позицию в меню. Например, необходимо где-то хранить строку, задающую текст, который будет выдаваться для каждой позиции. При работе с системой меню назначение клавиш мыши будет постоянно меняться. Частично эти изменения можно представить как изменения значений указателя, связанного с данной клавишей. Если пользователь выбрал позицию меню, которая определяется, например, как позиция 3 для клавиши 2, то соответствующая команда реализуется вызовом:

(*button2[3])();

Чтобы полностью оценить мощность конструкции указатель на функцию, стоит попытаться написать программу без нее. Меню можно изменять в динамике, если добавлять новые функции в таблицу команд. Довольно просто создавать в динамике и новые меню.

Указатели на функции помогают реализовать полиморфические подпрограммы, т.е. такие подпрограммы, которые можно применять к объектам различных типов:

typedef int (*CFT)(void*,void*);

void sort(void* base, unsigned n, unsigned int sz, CFT cmp) /* Сортировка вектора "base" из n элементов в возрастающем порядке; используется функция сравнения, на которую указывает cmp. Размер элементов равен "sz".

Алгоритм очень неэффективный: сортировка пузырьковым методом */ { for (int i=0; i<n-1; i++) for (int j=n-1; i<j; j--) { char* pj = (char*)base+j*sz; // b[j] char* pj1 = pj - sz;// b[j-1] if ((*cmp)(pj,pj1) < 0) { // поменять местами b[j] и b[j-1] for (int k = 0; k<sz; k++) { char temp = pj[k]; pj[k] = pj1[k]; pj1[k] = temp; } } } }




Содержание  Назад  Вперед