printПерегрузка функций и операций

printПравила перегрузки операций

  • Нельзя определить новый лексический символ для операции.
  • Нельзя изменить приоритет, арность (т.е. количество аргументов) и ассоциативность операций.
  • Нельзя перегрузить операцию для стандартных типов данных.
  • Нельзя перегружать операции . :: .* ?: sizeof typeid.
  • Операции = [] () -> можно перегружать только как методы.
  • Не рекомендуется перегружать операции , || &&.
  • Поведение перегруженных операций должно соответствовать поведению этих операций для стандартных типов данных: операция + не должна изменять своих аргументов, операция = должна возвращать ссылку на левый аргумент и т.п.

Формат перегрузки унарной операции @ как метода:
тип результата operator@()
или
тип результата operator@() const

Формат перегрузки унарной операции @ как функции:
тип результата operator@(имя класса & )
или
тип результата operator@(const имя класса & )

Исключение: В случае постфиксных ++ и -- добавляется фиктивный параметр типа int.
как метод: имя класса operator@(int)
как функция: имя класса operator@(имя класса & , int)

Формат перегрузки бинарной операции @ как метода:
тип результата operator@(тип параметра2)
или
тип результата operator@(тип параметра2) const
Левый аргумент операции передается как *this и может быть только определяемого типа. Конструкторы-преобразователи к левому аргументу не применяются.

Формат перегрузки бинарной операции @ как функции:
тип результата operator@(тип параметра1,тип параметра2)
где по крайней мере один из параметров должен относиться к определяемому типу. Если левый аргумент может иметь тип, отличный от определяемого, необходимо определять операцию как функцию.

Замечания:
  • При перегрузке операции как функции, эту функцию нужно делать дружественной классу только в том случае, если для её эффективной реализации необходим доступ к закрытым элементам класса, иначе лучше определять обычную функцию (см. тему "Рекомендации по проектированию")
  • Если операция присваивания не определяется программистом, компилятор создает её сам. В этом автоматически созданном методе вызываются операции присваивания для всех базовых классов и полей.
  • В большинстве случаев нет необходимости определять операцию присваивания самостоятельно.
  • Но если класс содержит указатели на динамически выделяемую память, то при присваивании произойдет дублирование идентичности этих значений. В результате изменение одного объекта приведёт к изменению другого объекта. Поэтому в случае использования указателей необходимо определять операцию присваивания самостоятельно.
  • Если присваивание объектов не требуется, рекомендуется объявить операцию присваивания в разделе private, не определяя её реализацию (в С++11 рекомендуется писать =delete после заголовка).
  • Кроме присваивания компилятор сам определяет операцию взятия адреса.
loading