Читаем Язык программирования C++. Пятое издание полностью

    int calc(const char*, const char*);

(c) int calc(char*, char*);

    int calc(char* const, char* const);

<p>6.7. Указатели на функции</p>

Указатель на функцию (function pointer) содержит адрес функции, а не объекта. Подобно любому другому указателю, указатель на функцию имеет вполне определенный тип. Тип функции определен типом ее возвращаемого значения и списком параметров. Имя функции не является частью ее типа.

// сравнивает длины двух строк

bool lengthCompare(const string &, const string &);

Эта функция имеет тип bool(const string&, const string&). Чтобы объявить указатель, способный указывать на эту функцию, достаточно расположить указатель вместо имени функции:

// pf указывает на функцию, получающую две константные ссылки

// на строки и возвращающую значение типа bool

bool (*pf)(const string &, const string &); // не инициализирован

Просматривая объявление с начала, можно заметить, что имени pf предшествует знак *, следовательно, pf — указатель. Справа расположен список параметров, означая, что pf указывает на функцию. Глядя влево, можно заметить, что возвращаемым типом функции является bool. Таким образом, указатель pf указывает на функцию, которая имеет два параметра типа const string& и возвращает значение типа bool.

Круглые скобки вокруг части *pf необходимы. Без них получится объявление функции pf(), возвращающей указатель на тип bool:

// объявление функции pf(), возвращающей указатель на тип bool

bool *pf(const string &, const string &);

Использование указателей на функцию

При использовании имени функции как значения функция автоматически преобразуется в указатель. Например, адрес функции lengthCompare() можно присвоить указателю pf следующим образом:

pf = lengthCompare;  // pf теперь указывает на функцию lengthCompare

pf = &lengthCompare // эквивалентное присвоение: оператор обращения к

                     // адресу необязателен

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

bool b1 = pf("hello", "goodbye");            // вызов lengthCompare

bool b2 = (*pf)("hello", "goodbye");         // эквивалентный вызов

bool b3 = lengthCompare("hello", "goodbye"); // эквивалентный вызов

Преобразование указателя на один тип функции в указатель на другой тип функции невозможно. Однако для обозначения того, что указатель не указывает на функцию, ему можно присвоить nullptr (см. раздел 2.3.2) или целочисленное константное выражение, означающее нуль:

string::size_type sumLength(const string&, const string&);

bool cstringCompare(const char*, const char*);

pf = 0;              // ok: pf не указывает на функцию

pf = sumLength;      // ошибка: разные типы возвращаемого значения

pf = cstringCompare; // ошибка: разные типы параметров

pf = lengthCompare;  // ok: типы функции и указателя совпадают точно

Указатели на перегруженные функции

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

void ff(int*);

void ff(unsigned int);

void (*pf1)(unsigned int) = ff; // pf1 указывает на ff(unsigned)

Компилятор использует тип указателя для выявления используемой версии перегруженной функции. Тип указателя должен точно соответствовать одной из версий перегруженной функции:

void (*pf2)(int) = ff;     // ошибка: нет версии с точно таким списком

                           // параметров

double (*pf3) (int*) = ff; // ошибка: тип возвращаемого значения

                           // функций ff и pf3 не совпадают

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных