Общие правила перегрузки операторов

Приведенные ниже правила накладывают ограничения на реализацию перегруженных операторов. Однако они не применяются к новым и удаленным операторам, которые рассматриваются отдельно.

  • Нельзя определить новые операторы, например ..

  • Не допускается переопределение операторов применительно ко встроенным типам данных.

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

    // rules_for_operator_overloading.cpp
    class Point
    {
    public:
        Point operator<( Point & );  // Declare a member operator
                                     //  overload.
        // Declare addition operators.
        friend Point operator+( Point&, int );
        friend Point operator+( int, Point& );
    };
    
    int main()
    {
    }
    

    В предыдущем примере кода оператор "меньше чем" объявляется как функция-член; однако операторы сложения объявляются как глобальные функции, имеющие дружественный доступ. Обратите внимание, что для каждого оператора можно предоставить несколько реализаций. Выше для оператора сложения предоставлены две реализации, обеспечивающие его коммутативность. Скорее всего, операторы, добавляющие к PointPointобъекту Point, int и т. д., могут быть реализованы.

  • Операторы подчиняются правилам приоритета, группирования и числа операндов, определяемым их типичным использованием со встроенными типами. Поэтому нет способа выразить концепцию "добавить 2 и 3 к объекту типа Point", ожидая, что 2 будет добавлено в координату x и 3, добавляемых в координату y .

  • Унарные операторы, объявленные как функции-члены, не принимают аргументов; при объявлении как глобальные функции они принимают один аргумент.

  • Бинарные операторы, объявленные как функции-члены, принимают один аргумент; при объявлении как глобальные функции они принимают два аргумента.

  • Если оператор можно использовать как унарный или двоичный оператор (&, +*и, и-), можно перегрузить каждый из них отдельно.

  • Перегруженные операторы не могут иметь аргументов по умолчанию.

  • Все перегруженные операторы, кроме назначения (operator=), наследуются производными классами.

  • Первым аргументов операторов, перегруженных в виде функций-членов, всегда является тип класса объекта, для которого вызывается этот оператор (класса, в котором объявлен оператор, или класса, производного от этого класса). Для первого аргумента никакие преобразования не предоставляются.

Обратите внимание, что значение любого оператора можно полностью изменить. Это включает в себя значение адреса (&), назначения (=) и операторов вызова функций. Кроме того, эквивалентность, на которую можно полагаться при использовании встроенных типов, может быть изменена при перегрузке операторов. Например, после полного вычисления следующие четыре оператора обычно эквивалентны:

var = var + 1;
var += 1;
var++;
++var;

Для типов классов с перегруженными операторами на такую эквивалентность полагаться невозможно. Более того, некоторые из неявных требований, существующих при использовании этих операторов для базовых типов, для перегруженных операторов ослабляются. Например, +=оператор добавления или назначения требует, чтобы левый операнд был l-значением при применении к базовым типам. Такое требование не требуется при перегрузке оператора.

Примечание.

Для согласованности при определении перегруженных операторов рекомендуется следовать модели для встроенных типов. Если семантика перегруженного оператора существенно отличается от его значения в других контекстах, это может скорее запутывать ситуацию, чем приносить пользу.

См. также

Перегрузка операторов