13.6.3. Указатели на статические члены класса

13.6.3. Указатели на статические члены класса

Между указателями на статические и нестатические члены класса есть разница. Синтаксис указателя на член класса не используется для обращения к статическому члену. Статические члены – это глобальные объекты и функции, принадлежащие классу. Указатели на них – это обычные указатели. (Напомним, что статической функции-члену не передается указатель this.)

Объявление указателя на статический член класса выглядит так же, как и для указателя на объект, не являющийся членом класса. Для разыменования указателя никакой объект не требуется. Рассмотрим класс Account:

class Account {

public:

static void raiseInterest( double incr );

static double interest() { return _interestRate ; }

double amount() { return _amount; }

private:

static double _interestRate;

double _amount;

string _owner;

};

inline void Account::raiseInterest( double incr )

{

_interestRate += incr;

}

Тип &_interestRate – это double*:

// это неправильный тип для &_interestRate

double Account::*

Определение указателя на &_interestRate имеет вид:

// правильно: double*, а не double Account::*

double *pd = &Account::_interestRate;

Этот указатель разыменовывается так же, как и обычный, объект класса для этого не требуется:

Account unit;

// используется обычный оператор разыменования

double daily = *pd / 365 * unit._amount;

Однако, поскольку _interestRate и _amount – закрытые члены, необходимо иметь статическую функцию-член interest() и нестатическую amount().

Указатель на interest() – это обычный указатель на функцию:

// правильно

double (*)()

а не на функцию-член класса Account:

// неправильно

double (Account::*)()

Определение указателя и косвенный вызов interest() реализуются так же, как и для обычных указателей:

// правильно: double(*pf)(), а не double(Account::*pf)()

double(*pf)() = &Account::interest;

double daily = pf() / 365 * unit.amount();

Упражнение 13.11

К какому типу принадлежат члены _screen и _cursor класса Screen?

Упражнение 13.12

Определите указатель на член и инициализируйте его значением Screen::_screen; присвойте ему значение Screen::_cursor.

Упражнение 13.13

Определите typedef для каждой из функций-членов класса Screen.

Упражнение 13.14

Указатели на члены можно также объявлять как данные-члены класса. Модифицируйте определение класса Screen так, чтобы оно содержало указатель на его функцию-член того же типа, что home() и end().

Упражнение 13.15

Модифицируйте имеющийся конструктор класса Screen (или напишите новый) так, чтобы он принимал параметр типа указателя на функцию-член класса Screen, для которой список формальных параметров и тип возвращаемого значения такие же, как у home() и end(). Реализуйте для этого параметра значение по умолчанию и используйте параметр для инициализации члена класса, описанного в упражнении 13.14. Напишите функцию-член Screen, позволяющую пользователю задать ее значение.

Упражнение 13.16

Определите перегруженный вариант repeat(), который принимает параметр типа cursorMovements.