Это объявление пытается определить обычную функцию по имени p, которая возвращает указатель на член класса Screen типа char. Поскольку объявляется обычная функция, за объявлением не может быть спецификатора const.

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

// pmf указывает на член класса Screen, не получающий аргументов и

// возвращающий тип char

pmf = &Screen::get; // нужно явно использовать оператор обращения к

                    // адресу

pmf = Screen::get;  // ошибка: нет преобразования в указатель для

                    // функций-членов

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

Как и при использовании указателя на переменную-член, для вызова функции-члена через указатель на член класса используются операторы .* и ->*:

Screen myScreen, *pScreen = &myScreen

// вызов функции, на которую указывает указатель pmf объекта,

// на который указывает указатель pScreen

char c1 = (pScreen->*pmf)();

// передает аргументы 0, 0 версии функции get() с двумя параметрами

// объекта myScreen

char c2 = (myScreen.*pmf2)(0, 0);

Вызовы (myScreen->*pmf)() и (pScreen.*pmf2)(0,0) требуют круглых скобок, поскольку приоритет оператора вызова выше, чем приоритет оператора указателя на член класса.

Без круглых скобок вызов myScreen.*pmf() был бы интерпретирован как myScreen.*(pmf()).

Этот код требует вызвать функцию pmf() и использовать ее возвращаемое значение как операнд оператора указателя на член класса (.*). Но pmf — не функция, поэтому данный код ошибочен.

Из-за разницы приоритетов операторов вызова объявления указателей на функции-члены и вызовы через такие указатели должны использовать круглые скобки: (С::*p)(parms) и (obj.*p) (args).

Использование псевдонимов типов для указателей на члены

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

// Action - тип, способный указывать на функцию-член класса Screen,

// возвращающую тип char и получающую два аргумента типа pos

using Action =

 char (Screen::*)(Screen::pos, Screen::pos) const;

Action — это другое имя для типа "указатель на константную функцию-член класса Screen, получающую два параметра типа pos и возвращающую тип char". Используя этот псевдоним, можно упростить определение указателя на функцию get() следующим образом:

Action get = &Screen::get; // get указывает на член get() класса Screen

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

// action() получает ссылку на класс Screen и указатель на его

// функцию-член

Screen& action(Screen&, Action = &Screen::get);

Функция action() получает два параметра, которые являются ссылками на объект класса Screen, и указатель на функцию-член класса Screen, получающую два параметра типа pos и возвращающую тип char. Функцию action() можно вызвать, передав ей указатель или адрес соответствующей функции-члена класса Screen:

Screen myScreen;

// эквивалентные вызовы:

action(myScreen);      // использует аргумент по умолчанию

action(myScreen, get); // использует предварительно определенную

                       // переменную get

action(myScreen, &Screen::get); // передает адрес явно

Псевдонимы типа облегчают чтение и написание кода, использующего указатели.

Таблицы указателей на функцию-член
Перейти на страницу:

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