Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

// Пример функции обратного вызова

bool updateProgress(int pct) {

 std::cout << pct << "% complete...\n";

 return(true);

}

// Этот typedef делает программный код более понятным

typedef bool (*FuncPtrBoolInt)(int);

// Функция, которая выполняется достаточно длительное время

void longOperation(FuncPtrBoolInt f) {

 for (long l=0; l < 100000000; l++)

 if (l % 10000000 == 0)

 f(l/1000000);

}

int main {

 longOperation(updateProgress); //
нормально

}

Обсуждение

В ситуации, которая показана в примере 15.1, применение указателя на функцию является хорошим решением, если

UpdateProgress
и
longOperation
ничего не должны знать друг о друге. Например, функцию, которая обновляет индикатор состояния процесса в диалоговом окне пользовательского интерфейса (user interface — UI), в окне консольного режима или где-то еще, не заботит контекст, в котором она вызывается. Аналогично функция
longOperation
может быть частью некоторого программного интерфейса загрузки данных, которого не заботит место вызова: из графического UI, из окна консольного режима или из фонового процесса.

Сначала потребуется определить сигнатуру функции, которую вы планируете вызывать, и создать для нее

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

bool (*f)(int); // f - имя переменной

Вы можете справедливо возразить, что здесь нет ничего особенного и я просто излишне драматизирую ситуацию. Но что вы скажете, если требуется определить вектор

vector
таких указателей?

vector<bool (*)(int)> vf;

Или их массив?

bool (*af[10])(int);

Форма представления указателей на функции отличается от обычных переменных С++, которые обычно задаются в виде (квалифицированного) имени типа, за которым идет имя переменной. Поэтому они вносят путаницу при чтении программного кода.

Итак, в примере 15.1 я использовал следующий

typedef
.

typedef bool (*FuncPtrBoolInt)(int);

Сделав это, я могу свободно объявлять указатели функций с сигнатурой, возвращающей значение

bool
и принимающей единственный аргумент, как это я бы делал для параметра любого другого типа, например.

void longOperation(FuncPtrBoolInt f) { // ...

Теперь все, что надо сделать в

longOperation
, — это вызвать
f
,
как если бы это была любая обычная функция.

f(l/1000000);

Таким образам, здесь

f
может быть любой функцией, которая принимает аргумент целого типа и возвращает
bool
. Предположим, что в вызывающей функции
longOperation
не требуется обеспечивать продвижение индикатора состояния процесса. Тогда ей можно передать указатель на функцию без операций.

bool whoCares(int i) {return(true);}

//...

longOperation(whoCares);

Более важно то, что выбор функции, передаваемой

longOperation
, может осуществляться динамически на этапе выполнения.

15.2. Применение указателей для членов класса

Проблема

Требуется обеспечить адресную ссылку на данное-член или на функцию-член.

Решение

Используйте имя класса и оператор области видимости (

::
) со звездочкой для правильного квалифицирования имени. Пример 15.2 показывает, как это можно сделать.

Пример 15.2. Получение указателя на член класса

#include <iostream>

#include <string>

class MyClass {

public:

 MyClass : ival_(0), sval_("foo") {}

 ~MyClass {}

 void incr {++ival_;}

 void decr {ival_--;}

private:

 std::string sval_;

 int ival_;

};

int main {

 MyClass obj;

 int MyClass::* mpi = &MyClass::ival_; // Указатели на

 std::string MyClass::* mps = &MyClass::sval_; // данные-члены

 void (MyClass::*mpf); // Указатель на функцию-член, у которой

// нет параметров и которая возвращает void

 void (*pf); // Обычный указатель на функцию

 int* pi = &obj.ival_; // int-указатель, ссылающийся на переменную-член

// типа int, - все нормально.

 mpf = &MyClass::incr; // Указатель на функцию-член. Вы не можете

// записать это значение в поток. Посмотрите в

// отладчике, как это значение выглядит.

 pf = &MyClass::incr; // Ошибка: &MyClass::inc не является экземпляром

// функции

 std::cout << "mpi = " << mpi << '\n';

 std::cout << "mps = " << mps << '\n';

 std::cout << "pi = " << pi << '\n';

Поделиться:
Популярные книги

Печать Пожирателя

Соломенный Илья
1. Пожиратель
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Печать Пожирателя

Привет из Загса. Милый, ты не потерял кольцо?

Лисавчук Елена
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Привет из Загса. Милый, ты не потерял кольцо?

Мастер 2

Чащин Валерий
2. Мастер
Фантастика:
фэнтези
городское фэнтези
попаданцы
технофэнтези
4.50
рейтинг книги
Мастер 2

Нечто чудесное

Макнот Джудит
2. Романтическая серия
Любовные романы:
исторические любовные романы
9.43
рейтинг книги
Нечто чудесное

Клан

Русич Антон
2. Долгий путь домой
Фантастика:
боевая фантастика
космическая фантастика
5.60
рейтинг книги
Клан

Имя нам Легион. Том 3

Дорничев Дмитрий
3. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 3

Запасная дочь

Зика Натаэль
Фантастика:
фэнтези
6.40
рейтинг книги
Запасная дочь

Убивать чтобы жить 7

Бор Жорж
7. УЧЖ
Фантастика:
героическая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 7

У врага за пазухой

Коваленко Марья Сергеевна
5. Оголенные чувства
Любовные романы:
остросюжетные любовные романы
эро литература
5.00
рейтинг книги
У врага за пазухой

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Генерал Скала и ученица

Суббота Светлана
2. Генерал Скала и Лидия
Любовные романы:
любовно-фантастические романы
6.30
рейтинг книги
Генерал Скала и ученица

Оцифрованный. Том 1

Дорничев Дмитрий
1. Линкор Михаил
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Оцифрованный. Том 1

Его маленькая большая женщина

Резник Юлия
Любовные романы:
современные любовные романы
эро литература
8.78
рейтинг книги
Его маленькая большая женщина

Хуррит

Рави Ивар
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Хуррит