|
Программирование >> Инициализация объектов класса, структура
всем указателям на функции-член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() , которую мы обсуждали в начале этого раздела. Теперь она будет принимать указатель на функцию-член:
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |