Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Липпман.doc
Скачиваний:
8
Добавлен:
14.08.2019
Размер:
7.54 Mб
Скачать

13.6. Указатель на член класса

Предположим, что в нашем классе Screen определены четыре новых функции-члена: forward(), back(), up() и down(), которые перемещают курсор соответственно вправо, влево, вверх и вниз. Сначала мы должны объявить их в теле класса:

class Screen {

public:

inline Screen& forward();

inline Screen& back();

inline Screen& end();

inline Screen& up();

inline Screen& down();

// другие функции-члены не изменяются

private:

inline int row();

// другие функции-члены не изменяются


};

Функции-члены forward() и back() перемещают курсор на один символ. По достижении правого нижнего или левого верхнего угла экрана курсор переходит в противоположный угол.

inline Screen& Screen::forward()

{ // переместить _cursor вперед на одну экранную позицию

++_cursor;

// если достигли конца экрана, перепрыгнуть в противоположный угол

if ( _cursor == _screen.size() )

home();

return *this;

}

inline Screen& Screen::back()

{ // переместить _cursor назад на одну экранную позицию

// если достигли начала экрана, перепрыгнуть в противоположный угол

if ( _cursor == 0 )

end();

else

--_cursor;

return *this;


}

end() перемещает курсор в правый нижний угол экрана и является парной по отношению к функции-члену home():

inline Screen& Screen::end()

{

_cursor = _width * _height - 1;

return *this;


}

Функции up() и down() перемещают курсор вверх и вниз на одну строку. По достижении верхней или нижней строки курсор остается на месте и подается звуковой сигнал:

const char BELL = '\007';

inline Screen& Screen::up()

{ // переместить _cursor на одну строку вверх

// если уже наверху, остаться на месте и подать сигнал

if ( row() == 1 ) // наверху?

cout << BELL << endl;

else

_cursor -= _width;

return *this;

}

inline Screen& Screen::down()

{

if ( row() == _height ) //внизу?

cout << BELL << endl;

else

_cursor += _width;

return *this;


}

row() – это закрытая функция-член, которая используется в функциях up() и down(), возвращая номер строки, где находится курсор:

inline int Screen::row()

{ // вернуть текущую строку

return ( _cursor + _width ) / height;


}

Пользователи класса Screen попросили нас добавить функцию repeat(), которая повторяет указанное действие n раз. Ее реализация могла бы выглядеть так:

Screen &repeat( char op, int times )

{

switch( op ) {

case DOWN: // n раз вызвать Screen::down()

break;

case DOWN: // n раз вызвать Screen::up()

break;

// ...

}


}

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

В более общей реализации параметр op заменяется параметром типа указателя на функцию-член класса Screen. Теперь repeat() не должна сама устанавливать, какую операцию следует выполнить, и всю инструкцию switch можно удалить. Определение и использование указателей на члены класса – тема последующих подразделов.