Упражнение 14.20. Определите оператор суммы и составной оператор присвоения для класса Sales_data.

Упражнение 14.21. Напишите операторы класса Sales_data так, чтобы + осуществлял сложение, а оператор += вызывал оператор +. Обсудите недостатки этого подхода по сравнению со способом, которым эти операторы были определены в разделах 14.3 и 14.4.

Упражнение 14.22. Определите версию оператора присвоения, способного присвоить строку, представляющую ISBN, объекту класса Sales_data.

Упражнение 14.23. Определите в версии класса StrVec оператор присвоения для типа initializer_list.

Упражнение 14.24. Примите решение, нуждается ли класс из упражнения 7.40 раздела 7.5.1 в операторах копирования и присваивания при перемещении. Если да, то определите эти операторы.

Упражнение 14.25. Реализуйте все остальные операторы присвоения, которые должен определить класс. Объясните, какие типы должны использоваться как операнды и почему.

<p>14.5. Оператор индексирования</p>

Классы, представляющие контейнеры, способные возвращать элементы по позиции, зачастую определяют оператор индексирования operator[].

Оператор индексирования должен быть определен как функция-член класса.

Согласно общепринятому смыслу индексирования, оператор индексирования обычно возвращает ссылку на выбранный элемент. Возвращающий ссылку оператор индексирования применим с обеих сторон оператора присвоения. Следовательно, имеет смысл определить и константную, и неконстантную версии этого оператора. При применении к константному объекту оператор индексирования должен возвращать ссылку на константу, чтобы предотвратить присвоение возвращенному объекту.

Если у класса есть оператор индексирования, он обычно должен быть определен в двух версиях: возвращающей простую ссылку и являющуюся константной функцией-членом, а следовательно, возвращающую ссылку на константу.

В качестве примера определим оператор индексирования для класса StrVec (см. раздел 13.5):

class StrVec {

public:

 std::string& operator[](std::size_t n)

  { return elements[n]; }

 const std::string& operator[](std::size_t n) const

  { return elements[n]; }

 // другие члены, как в разделе 13.5

private:

 std::string *elements; // указатель на первый элемент массива

};

Эти операторы можно использовать таким же образом, как и индексирование вектора или массива. Поскольку оператор индексирования возвращает ссылку на элемент, если объект класса StrVec не константен, то этому элементу можно присвоить значение; если индексируется константный объект, присвоение невозможно:

// svec - объект класса StrVec

const StrVec cvec = svec; // копировать элементы из svec в cvec

// если у svec есть элементы, выполнить функцию empty() класса string

// для первого

if (svec.size() && svec[0].empty()) {

 svec[0] = "zero"; // ok: индексирование возвращает ссылку на строку

 cvec[0] = "Zip";  // ошибка: индексация cvec возвращает ссылку на

                   // константу

}

Упражнения раздела 14.5

Упражнение 14.26. Определите операторы индексирования для классов StrVec, String, StrBlob и StrBlobPtr.

<p>14.6. Операторы инкремента и декремента</p>

Операторы инкремента (++) и декремента (--) обычно реализуют для классов итераторов. Эти операторы позволяют перемещать итератор с элемента на элемент последовательности. Язык никак не требует, чтобы эти операторы были членами класса. Но поскольку они изменяют состояние объекта, с которым работают, лучше сделать их членами класса.

Для встроенных типов есть префиксные и постфиксные версии операторов инкремента и декремента. Ничего удивительного, что для собственных классов также можно определить префиксные и постфиксные версии этих операторов. Давайте сначала рассмотрим префиксные версии, а затем реализуем постфиксные.

Классы, определяющие операторы инкремента или декремента, должны определять как префиксные, так и постфиксные их версии. Обычно эти операторы определяют как функции-члены.

Определение префиксных версий операторов инкремента и декремента

Для иллюстрации операторов инкремента и декремента определим их для класса StrBlobPtr (см. раздел 12.1.6):

class StrBlobPtr {

public:

 // инкремент и декремент

Перейти на страницу:

Похожие книги