Управление копированием (copy control). Специальные функции-члены, которые определяют действия, осуществляемые при копировании, присвоении и удалении объектов класса. Если эти функции не определены в классе явно, компилятор синтезирует их самостоятельно.
Функцияmove(). Библиотечная функция, обычно используемая для связи ссылки r-значения с l-значением. Вызов функции move() неявно обещает, что объект не будет использован для перемещения, кроме его удаления или присвоения нового значения.
Глава 14
Перегрузка операторов и преобразований
Как упоминалось в главе 4, язык С++ предоставляет для встроенных типов множество операторов и автоматических преобразований. Они позволяют создавать разнообразные выражения, где используются разные типы данных.
Язык С++ позволяет переопределять смысл операторов, применяемых для объектов типа класса, а также определять для класса функции преобразования типов. Функции преобразования типа класса используются подобно встроенным преобразованиям для неявного преобразования (при необходимости) объекта одного типа в другой.
Sales_item (см. раздел 1.5.1) определял операторы ввода, вывода и суммы, сумму двух объектов класса Sales_item можно вывести так:
cout << item1 + item2; //
Класс Sales_data (см. раздел 7.1), напротив, еще не имеет перегруженных операторов, поэтому код вывода суммы его объектов окажется более подробным, а следовательно, менее ясным:
print(cout, add(data1, data2)); //
//
Перегруженный оператор — это функция со специальным именем, состоящим из ключевого слова operator, сопровождаемого символом определяемого оператора. Подобно любой другой функции, перегруженный оператор имеет тип возвращаемого значения и список параметров.
Количество параметров функции перегруженного оператора совпадает с количеством операндов оператора. У унарного оператора — один параметр; у бинарного — два. В бинарном операторе левый операнд передается первому параметру, а правый операнд — второму. За исключением перегруженного оператора вызова функции, operator(), у перегруженного оператора не может быть аргументов по умолчанию (см. раздел 6.5.1).
Если перегруженный оператор является функцией-членом, то первый (левый) операнд связывается с неявным указателем this (см. раздел 7.1.2). Поскольку первый операнд неявно связан с указателем this, функция оператора-члена будет иметь на один явный параметр меньше, чем операндов у оператора.
this соответствует левому операнду. У операторов-членов на один явный параметр меньше, чем операндов.
Функция оператора должна быть либо членом класса, либо иметь по крайней мере один параметр типа класса:
//
int operator*(int, int);
Это ограничение означает невозможность изменить смысл оператора, относящегося к операндам встроенного типа.
Перегрузить можно многие, но не все операторы. Табл. 14.1 демонстрирует, может ли оператор быть перегружен. Перегрузка операторов new и delete рассматривается в разделе 19.1.1 .
Перегрузить можно только существующие операторы и нельзя изобрести новые символы операторов. Например, нельзя определить оператор operator** для возведения числа в степень.
Таблица 14.1. Операторы
| Операторы, которые могут быть перегружены | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
+ | - | * | / | % | ^ | ||||||
& | | | ~ | ! | , | = | ||||||
< | > | <= | >= | ++ | -- | ||||||
<< | >> | == | != | && | || | ||||||
+= | -= | /= | %= | ^= | &= | ||||||
|= | *= | <<= | >>= | [] | () | ||||||
-> | ->* | new | new [] | delete | delete [] | ||||||
| Операторы, которые не могут быть перегружены | |||||||||||
:: | .* | . | ?: | ||||||||
Четыре символа (+, -, * и &) служат и унарными операторами, и бинарными. Перегружен может быть один или оба из этих операторов. Определяемый оператор задает количество параметров:
x == y + z;
Это будет эквивалентно x == (y + z).