ScreenPtr parr( *parray, arrSize ); // правильно: указывает на массив
Теперь мы готовы определить в ScreenPtr перегруженные операторы инкремента и декремента. Однако они бывают двух видов: префиксные и постфиксные. К счастью, можно определить оба варианта. Для префиксного оператора объявление не содержит ничего неожиданного:
class ScreenPtr {
public:
Screen& operator++();
Screen& operator--();
// ...
};
Такие операторы определяются как унарные операторные функции. Использовать префиксный оператор инкремента можно, к примеру, следующим образом: const int arrSize = 10; Screen *parray = new Screen[ arrSize ]; ScreenPtr parr( *parray, arrSize ); for ( int ix = 0; ix
Определения этих перегруженных операторов приведены ниже:
Screen& ScreenPtr::operator++()
{
if ( size == 0 ) {
cerr "не могу инкрементировать указатель для одного объекта\n";
return *ptr;
}
if ( offset = size - 1 ) {
cerr "уже в конце массива\n";
return *ptr;
}
++offset;
return *++ptr;
}
Screen& ScreenPtr::operator--()
{
if ( size == 0 ) {
cerr "не могу декрементировать указатель для одного объекта\n";
return *ptr;
}
if ( offset = 0 ) {
cerr "уже в начале массива\n";
return *ptr;
}
--offset;
return *--ptr;
}
Чтобы отличить префиксные операторы от постфиксных, в объявлениях последних имеется дополнительный параметр типа int. В следующем фрагменте объявлены префиксные и постфиксные варианты операторов инкремента и декремента для класса ScreenPtr:
class ScreenPtr {
public:
Screen& operator++(); // префиксные операторы
Screen& operator--();
Screen& operator++(int); // постфиксные операторы
Screen& operator--(int);
// ...
};
Ниже приведена возможная реализация постфиксных операторов:
Screen& ScreenPtr::operator++(int)
{
if ( size == 0 ) {
cerr "не могу инкрементировать указатель для одного объекта\n";
return *ptr;
}
if ( offset == size ) {
cerr "уже на один элемент дальше конца массива\n";
return *ptr;
}
++offset;
return *ptr++;
}
Screen& ScreenPtr::operator--(int)
{
if ( size == 0 ) {
cerr "не могу декрементировать указатель для одного объекта\n";
return *ptr;
}
if ( offset == -1 ) {
cerr "уже на один элемент раньше начала массива\n";
return *ptr;
}
--offset;
return *ptr--;
}
Обратите внимание, что давать название второму параметру нет необходимости, поскольку внутри определения оператора он не употребляется. Компилятор сам подставляет для него значение по умолчанию, которое можно игнорировать. Вот пример использования постфиксного оператора:
const int arrSize = 10;
Screen *parray = new Screen[ arrSize ];
ScreenPtr parr( *parray, arrSize );
for ( int ix = 0; ix
При его явном вызове необходимо все же передать значение второго целого аргумента. В случае нашего класса ScreenPtr это значение игнорируется, поэтому может быть любым:
parr.operator++(1024); // вызов постфиксного operator++
Перегруженные операторы инкремента и декремента разрешается объявлять как дружественные функции. Изменим соответствующим образом определение класса ScreenPtr:
class ScreenPtr {
// объявления не членов
friend Screen& operator++( Screen & ); // префиксные операторы
friend Screen& operator--( Screen & );
friend Screen& operator++( Screen &, int); // постфиксные операторы
friend Screen& operator--( Screen &, int);
public: