return ret; //
}
Для выполнения фактического действия каждый из этих операторов вызывает собственную префиксную версию. Например, постфиксный оператор инкремента использует такой вызов префиксного оператора инкремента:
++*this
Этот оператор проверяет безопасность приращения и либо передает исключение, либо осуществляет приращение значения curr. Если функция check() не передает исключения, постфиксные функции завершают работу, возвращая сохраненные ранее копии значений. Таким образом, после выхода сам объект будет изменен, но возвращено будет первоначальное, не измененное значение.
int не используется, имя ему присваивать не нужно.
Как упоминалось в разделе 14.1, в качестве альтернативы использованию перегруженного оператора в выражении можно вызвать его явно. Если постфиксная версия задействуется при помощи вызова функции, то следует передать значение и для целочисленного аргумента:
StrBlobPtr p(a1); //
p.operator++(0); //
p.operator++(); //
Переданное значение обычно игнорируется, но оно позволяет предупредить компилятор о том, что требуется именно постфиксная версия оператора.
Упражнение 14.27. Добавьте в класс StrBlobPtr операторы инкремента и декремента.
Упражнение 14.28. Определите для класса StrBlobPtr операторы сложения и вычитания, чтобы они реализовали арифметические действия с указателями (см. раздел 3.5.3).
Упражнение 14.29. Почему не были определены константные версии операторов инкремента и декремента?
14.7. Операторы доступа к членам
Операторы обращения к значению (*) и стрелка (->) обычно используются в классах, представляющих итераторы, и в классах интеллектуального указателя (см. раздел 12.1). Вполне логично добавить эти операторы в класс StrBlobPtr:
class StrBlobPtr {
public:
std::string& operator*() const {
auto p = check(curr, "dereference past end");
return (*p)[curr]; //
//
}
std::string* operator->() const {
//
return &this->operator*();
}
//
};
Оператор обращения к значению проверяет принадлежность curr диапазону, и если это так, то возвращает ссылку на элемент, обозначенный значением curr. Оператор стрелки не делает ничего сам, он вызывает оператор обращения к значению и возвращает адрес возвращенного им элемента.
Следует заметить, что эти операторы определены как константные члены. В отличие от операторов инкремента и декремента, выборка элемента никак не изменяет состояния объекта класса StrBlobPtr. Обратите также внимание на то, что эти операторы возвращают ссылку или указатель на неконстантную строку. Причина этого в том, что объект класса StrBlobPtr, как известно, может быть связан только с неконстантным объектом класса StrBlob (см. раздел 12.1.6).
Эти операторы можно использовать таким же способом, которым используются соответствующие операторы с указателями и итераторами вектора:
StrBlob a1 = {"hi", "bye", "now"};
StrBlobPtr p(a1); //
*p = "okay"; //
cout << p->size() << endl; //
cout << (*p).size() << endl; //