void (*psf)(double) = &Account::raiseInterest;
psf( 0.0025 );
}
Account ac1( 5000, "Asterix" );
Account ac2( 10000, "Obelix" );
if ( compareRevenue( ac1, &ac2 ) & 0 )
cout ac1.owner()
"is richer than "
ac2.owner() "\n";
else
cout ac1.owner()
" is poorer than"
ac2.owner() "\n";
return 0;
}
Упражнение 13.8
Пусть дан класс Y с двумя статическими данными-членами и двумя статическими функциями-членами:
class X {
public:
X( int i ) { _val = i; }
int val() { return _val; }
private:
int _val;
};
class Y {
public:
Y( int i );
static X xval();
static int callsXval();
private:
static X _xval;
static int _callsXval;
};
Инициализируйте _xval значением 20, а _callsXval значением 0.
Упражнение 13.9
Используя классы из упражнения 13.8, реализуйте обе статические функции-члена для класса Y. callsXval() должна подсчитывать, сколько раз вызывалась xval().
Упражнение 13.10
Какие из следующих объявлений и определений статических членов ошибочны? Почему?
// example.h
class Example {
public:
static double rate = 6.5;
static const int vecSize = 20;
static vectordouble vec(vecSize);
};
// example.c
#include "example.h "
double Example::rate;
vectordouble Example::vec;
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() необходимо модифицировать. Вторая проблема – размер функции. Поскольку приходится проверять все возможные функции-члены, то исходный текст становится громоздким и неоправданно сложным.