Почему перегрузка оператора для указателей не позволяет работать?

В соответствии с комментарием в этом ответе ссылки были представлены в основном для поддержки перегрузки операторов, которая цитирует Bjarne Stroustrup:

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

Это означает, что перегрузка оператора не может работать с указателем. Но это не ясно объясняет, почему перегрузка оператора указателями не может работать. Почему бы не перегружать работу оператора указателями?

IMO, где используются ссылки, указатели также могут использоваться на своем месте.

Ответ 1

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

Предположим, что это разрешено, тогда вы должны написать:

struct A{};
A a, *pa, b;

a = pa ;//doesn't look good, also not intuitive. (not real C++)

Это не выглядит хорошо, потому что на левой стороне у вас нет указателя, справа - указатель. Выглядит очень странно. Кроме того, поскольку типы не совпадают, это не выглядит очень интуитивным относительно того, что именно он делает. Я имею в виду, что вы назначаете указатель на не указатель; что такое задание должно делать? Копирование содержимого адреса, на которое указывает указатель на пункт назначения (не указатель), не очень интуитивно понятен.

С другой стороны, поскольку это разрешено с ссылкой (реальность, а не предположение):

a = b; //looks good, intuitive, as now both side is same type

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

Было бы также интересно отметить, что не только b передается по ссылке (или указатель внизу), a также передается функции указателем, потому что мы знаем в функции ключевое слово this на самом деле является указателем.

Итак, ссылки были введены в С++, чтобы все выглядело хорошо и интуитивно понятно для программистов, иначе они будут указателями внизу. Фактически, большинство компиляторов реализуют ссылки с помощью указателей (указатель-механизм) внутри.

Ответ 2

Почему он не работает для указателей? Потому что это неоднозначно. Будет ли

ostream* operator<<(ostream* s, const char* c);

матч

cout << 'a';

или

cout << "a";

?

Кроме того, вы не можете использовать адрес (&) с временным. Что это должно сделать:

complex<double> a, b, c;
cout << a + b * c;

так как b * c является временным, и сумма также.

?

Ответ 3

Если оператор с плюсом перегружен для тяжелого класса, вам нужно будет написать либо a + b (по значению, неэффективно), либо &a + &b (уродливый и сложный), чтобы добавить два объекта этого класса. Но со ссылками вы получаете by-ref даже при написании a + b.

Ответ 4

Поскольку большинство операторов уже имеют альтернативное установленное значение при применении к указателям.

Ответ 5

Оператор перегружает работу с объектами, но указатель сам по себе не является объектом. Он указывает на объект.

Ответ 6

Рассмотрим утверждение

c= a+b         

где оператор + был перегружен. Этот оператор может интерпретироваться компилятором как

c=operator+ (a, b)

Так как здесь адреса переменных не передаются, поэтому мы не можем их собирать в переменных указателя.

Если мы хотим собрать их в переменных указателя, тогда мы должны изменить оператор следующим образом:

c=&a+&b;

Но это означает, что мы пытаемся добавить адреса a и b, а не их значения. В такие моменты для сохранения памяти могут использоваться только ссылки.

Ответ 7

Операторы не могут быть перегружены, если задействованы оба типа типов (например, int, float или любой указатель). Вы можете перегрузить оператор для одного класса и одного примитивного типа (или просто использовать преобразование типов). Например, вы можете добавить std::string и const char *.

Ответ 8

Из этого следует, что оператор перегрузка не может работать с указателем.

Это не означает, что вообще. В нем говорится, что предоставление ссылок является существенным нотационным удобством, так что программисту не нужно свободно использовать адрес-оператора.

Также случается, что перегрузка оператора не работает с указателями, но в основном потому, что для нее нет синтаксиса. Зачем? Спросите Страустрапа.

Ваша ИМО правильная, если перед указателем используется оператор разыменования.

Ответ 9

Это 2019 год и у вас до сих пор нет доступа к классам нативных типов. Там нет никакого способа переопределить операторы на них.

Указатели (например, char, int, float и т.д.) Являются нативным типом. Вы можете создать объект, который ведет себя как указатель и операторы перегрузки [->, *], но он не будет перегружать [->, *] для собственного указателя. Вы также можете, например, создать объект, который ведет себя как int и перегружает [+, -, *,/], но не будет перегружать [+, -, *,/] в нативном int.

Для прагматического рационального, представьте хаос, если

this->member

имел пользовательское значение.

Ссылки - это не связанная тема, ИМХО.