Глава 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