Программирование >>  Инициализация объектов класса, структура 

1 ... 204 205 206 [ 207 ] 208 209 210 ... 395


всем указателям на функции-член1 класса можно присвоить значение 0

int (Screen::*pmf1)() = 0; int (Screen::*pmf2)() = sScreen::height;

pmf1 = pmf2;

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

pmf2 = sScreen::width;

должен быть сначала привязан к объекту или указателю на объект, чтобы получить this, и только после этого он применяется для вызова функции-члена. (В следующем подразделе мы покажем, как осуществить такую привязку.) Хотя для указателя на обычную функцию и для указателя на функцию-член используется один и тот же термин, их природа различна.

Синтаксис объявления указателя на функцию-член должен принимать во внимание тип класса. То же верно и в отношении указателей на данные-члены. Рассмотрим член height класса Screen. Его полный тип таков: член класса Screen типа short. Следовательно, полный тип указателя на height - это указатель на член класса Screen типа short:

short Screen::*

Определение указателя на член класса Screen типа short выглядит следующим образом:

short Screen::*ps Screen; Переменную ps Screen можно инициализировать адресом height:

short Screen::*ps Screen = sScreen:: height; или присвоить ей адрес width:

short Screen::*ps Screen = sScreen:: width;

Переменной ps Screen разрешается присваивать указатель на width или height, так как они являются членами класса Screen типа short.

Несоответствие типов указателя на данные-члены и обычного указателя также связано с различием в их представлении. Обычный указатель содержит всю информацию, необходимую для обращения к объекту. Указатель на данные-члены следует сначала привязать к объекту или указателю на него, а лишь затем использовать для доступа к члену этого объекта. (В книге Inside the C++ Object Model ([gN96i]) также описывается представление указателей на члены.)

Указатель на функцию-член определяется путем задания типа возвращаемого функцией значения, списка ее параметров и класса. Например, следующий указатель, с помощью которого можно вызвать функции height() и width() , имеет тип указателя на функцию-член класса Screen без параметров, которая возвращает значение типа int:

int (Screen::*)()



typedef ScreenS (Screen::*Action)(); Action default = SScreen::home;

Следующий typedef определяет Action как альтернативное имя:

Action next = SScreen::forward;

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

ScreenS action( ScreenS, Action)();

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

Screen meScreen;

typedef ScreenS (Screen::*Action)(); Action default = SScreen::home;

extern ScreenS action( ScreenS, Sction = SScreen::display );

void ff()

action( myScreen );

action( myScreen, default );

action( myScreen, SScreen::end );

объект. Вызвать action() можно любым из следующих способов:

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

13.6.2. Работа с указателями на члены класса

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

Использование typedef может облегчить чтение объявлений указателей на члены. Например, для тина указатель на функцию-член класса Screen без параметров, которая возвращает ссылку на объект Screen , т.е.

ScreenS (Screen::*)()



int (Screen::*pmfi)() = sScreen::height;

Screens (Screen::*pmfS)( const Screens ) = sScreen::copy; Screen myScreen, *bufScreen; прямой вызов функции-члена

if ( myScreen.height() == bufScreen->height() ) bufScreen->copy( myScreen );

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

if ( (myScreen.*pmfi)() == (bufScreen->*pmfi)() )

(bufScreen->*pmfS)( myScreen );

(myScreen.*pmfi)()

Вызовы

(bufScreen->*pmfi)();

требуют скобок, поскольку приоритет оператора вызова () выше, чем приоритет взятия указателя на функцию-член. Без скобок

myScreen.*pmfi() интерпретируется как

myScreen.*(pmfi())

Это означает вызов функции pmfi() и привязку возвращенного ей значения к оператору (.*). Разумеется, тип pmifi не поддерживает такого использования, так что компилятор выдаст сообщение об ошибке.

typedef short Screen::*ps Screen;

Screen myScreen, *tmpScreen = new Screen( 10, 10 );

ps Screen pH = sScreen:: height; ps Screen pW = sScreen:: width;

tmpScreen->*pH = myScreen.*pH;

Указатели на данные-члены используются аналогично:

tmpScreen->*pW = myScreen.*pW;

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



1 ... 204 205 206 [ 207 ] 208 209 210 ... 395

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика