Оператор перегрузки = как функция-член - PullRequest
1 голос
/ 04 января 2012

C ++ позволяет перегрузить оператор = только как функцию-член, а не как глобальную функцию.

Брюс Экель говорит, что if it was possible to define operator= globally, then you might attempt to redefine the built-in = sign., и по этой причине вы можете перегрузить оператор = только как функцию-член.

если в C ++ уже определен оператор =, то почему другие операторы, такие как + - и т. Д., Не определены в C ++, поскольку они могут быть перегружены как функция, не являющаяся членом.

Ответы [ 5 ]

4 голосов
/ 04 января 2012

Компилятор генерирует оператор назначения копирования по умолчанию (operator =) для всех классов, которые не определяют свои собственные.Это означает, что глобальная перегрузка не будет выбрана ни при каких обстоятельствах.

0 голосов
/ 04 января 2012

Чтобы расширить комментарий @ ildjarn, семантика глобального встроенного = установлена ​​повсеместно; он вызывается при инициализации нового экземпляра класса с некоторым значением rvalue и вызывает соответствующий конструктор (основанный на типе значения r во время компиляции), который является хорошим способом обеспечения инициализации в стиле c вместо строго Требование инициализации всех переменных путем явного вызова конструктора. Перегрузка глобального оператора изменила бы слишком большую семантику языка, в то же время предоставив мало реальной информации о преимуществах - вы бы в корне изменили, как, какие и как называются конструкторы, и если вы чувствуете, что у вас есть причина сделать это через перегрузку глобальной =, есть большая вероятность, что вы ошибаетесь.

Элемент класса operator= перегружен, потому что он работает с уже существующим и инициализированным lvalue своего класса, и есть очевидные случаи, когда вы хотели бы иметь пользовательское поведение при изменении существующего объекта (например, только копирование определенных членов из значения r при пересчете других и оставлении одних в покое, или при правильном использовании ресурсов, удерживаемых указателем, для захвата нового ресурса без утечки памяти).

Там, где элемент operator= имеет дело с полным объектом lvalue, встроенная система начинается только с блока памяти соответствующего размера и значения. Конструкторы всех форм и форм - это предоставляемые языком интерфейсы для изменения поведения встроенного = без передачи вам контроля над самими семантиками. Мне было бы интересно посмотреть, что вы чувствуете вам нужно выполнить перегрузку глобального =, что нельзя сделать с помощью конструктора.

0 голосов
/ 04 января 2012

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

0 голосов
/ 04 января 2012

Похоже, было бы действительно сложно реализовать operator = () вне класса без ссылки на конкретную реализацию и закрытые члены.

Операторы типа «+», однако, иногда должны быть определены на глобальном уровне.Рассмотрим класс комплексных чисел.Я могу определить complex :: operator + (float) изнутри моего класса, но я должен определить operator + (float, complex) снаружи, потому что первый операнд не имеет тип моего класса.

Редактировать : Я должен был также упомянуть, что часто легко определить глобальные операторы, такие как operator +, без ссылки на конкретные детали реализации, используя другие операторы, определенные в классе.Например:

complex operator+(float lhs, complex rhs) {return complex(lhs, 0)+rhs;}
0 голосов
/ 04 января 2012

Оператор = (при использовании в качестве инициализации) тесно связан с конструкторами; когда вы кодируете SomeClass a = b;, вызывается какой-то конструктор SomeClass.

...