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

Указатель на функцию как параметр

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

// третий параметр имеет тип функции и автоматически обрабатывается как

// указатель на функцию

void useBigger(const string &s1, const string &s2,

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

// эквивалентное объявление: параметр явно определен как указатель

// на функцию

void useBigger(const string &s1, const string &s2,

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

При передаче функции как аргумента это можно сделать непосредственно. Аргумент будет автоматически преобразован в указатель:

// автоматическое преобразование функции lengthCompare в указатель

// на нее

useBigger(s1, s2, lengthCompare);

Как можно заметить в объявлении функции useBigger(), написание указателей на тип функций быстро становится утомительным. Псевдонимы типа (см. раздел 2.5.1), а также спецификатор decltype (см. раздел 2.5.3) позволяют упростить код, который использует указатели на функции:

// Func и Func2 имеют тип функции

typedef bool Func(const string&, const strings);

typedef decltype(lengthCompare) Func2; // эквивалентный тип

// FuncP и FuncP2 имеют тип указателя на функцию

typedef bool(*FuncP)(const string&, const string&);

typedef decltype(lengthCompare) *FuncP2; // эквивалентный тип

Здесь при определении типов использовано ключевое слово typedef. И Func, и Func2 являются типами функций, тогда как FuncP и FuncP2 — типы указателя. Следует заметить, что спецификатор decltype возвращает тип функции; автоматического преобразования в указатель не происходит. Поскольку спецификатор decltype возвращает тип функции, при необходимости получить указатель следует добавить символ *. Можно повторно объявить функцию useBigger(), используя любой из этих типов:

// эквивалентные объявления useBigger с использованием псевдонимов типа

void useBigger(const string&, const string&, Func);

void useBigger(const string&, const string&, FuncP2);

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

Возвращение указателя на функцию

Подобно массивам (см. раздел 6.3.3), нельзя возвратить тип функции, но можно возвратить указатель на тип функции. Точно так же тип возвращаемого значения следует писать как тип указателя; компилятор не будет автоматически рассматривать тип возвращаемого значения функции как соответствующий тип указателя. Как и при возвращении массива, безусловно, проще всего объявить функцию, которая возвращает указатель на функцию, при помощи псевдонима типа:

using F = int(int*, int);     // F - тип функции, а не указатель

using PF = int(*)(int*, int); // PF - тип указателя

Здесь для определения F как типа функции и PF как указателя на тип функции было использовано объявление псевдонима типа (см. раздел 2.5.1). Имейте в виду, что в отличие от параметров, имеющих тип функции, тип возвращаемого значения не преобразуется автоматически в тип указателя. Следует явно определить, что тип возвращаемого значения является типом указателя:

PF f1(int); // ok: PF - указатель на функцию; f1 возвращает указатель

            // на функцию

F f1(int);  // ошибка: F - тип функции; f1 не может возвратить функцию

F *f1(int); // ok: явное определение типа возвращаемого значения как

            // указателя на функцию

Конечно, функцию f1() также можно объявить непосредственно:

int (*f1(int))(int*, int);

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

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

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

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

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

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

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

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

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