Статическую функцию-член можно вызвать для объекта класса, пользуясь одним из операторов доступа. Ее также можно вызвать непосредственно, квалифицировав ее имя, даже если никаких объектов класса не объявлено. Вот небольшая программа, иллюстрирующая их применение:
#include iostream
#include "account.h"
bool limitTest( double limit )
{
// пока еще ни одного объекта класса Account не объявлено
// правильно: вызов статической функции-члена
return limit = Account::interest() ;
}
int main() {
double limit = 0.05;
if ( limitTest( limit ) )
{
// указатель на статическую функцию-член
// объявлен как обычный указатель
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';