Глава 16. Перегрузка операций_______________________________401
Определяя оператор-функцию, определяйте ее как друга, если вы считаете, что удобнее или дешевле обращаться к закрытым данным класса напрямую.
Однако если определены операции преобразования, возвращающие соответствующие закрытые элементы данных, то расширение дружелюбия класса на глобальные оператор-функции не является необходимым.
Индексная операция
Индексная операция operator [] может быть перегружена, что позволяет использовать нотацию массивов для сложных типов данных. Это очень полезно потому, что массив — это, вероятно, самая простая и наиболее популярная структура данных.
Для корректного определения операции индексирования массива необходимо помнить, что массивы можно использовать и как левосторонние, и как правосторонние аргументы.
int a [10];
for ( int j =0; j < 10; j++) {
a[j]=j; // массив слева
cout « a[j] « endl; // массив справа }
Для обеспечения симметрии массивов в контексте ваших классов следует определить операцию operator [], возвращающую левосторонние значения:
указатели на отдельные объекты. Рассмотрим следующее:
class Y
{
public:
// ...
Т operator[] ( unsigned int j) // ошибка: должна быть ссылка
{ return data ? data[j] : 0; } private:
unsigned int size;
T* data; // Т — некоторый тип данных }
Класс Y возвращает из data[j] копию объекта типа Y. Это прекрасно работает, когда объект Y выступает в роли правостороннего аргумента
Y у;
Т t = у[0]; // Правильно: возвращает копию y.data[0];
но когда Y является левосторонним аргументом
Т t;
у[0] = t; // Ошибка: требуется lvalue