Что не так с этими перегрузками операторов C ++?

0

Они были приведены в качестве примеров неправильного использования перегрузки оператора, но я не уверен, почему это так. Это с точки зрения С++, с которым я тоже не знаком. Может ли кто-нибудь объяснить, почему они не будут работать, если они будут использованы? Я знаю, что они не являются полными кодами, но я думаю, что проблема форматирования была подчеркнута здесь.

(1)

class Mystery                    //Line 1
{
  ...
  bool operator <= (Mystery);     //Line 2
  ...
};

bool Mystery::<=(Mystery rightObj)    //Line 3
{
  ...
}

(2)

class Mystery                       //Line 1
{
    ...
    bool operator <= (Mystery, Mystery);  //Line 2
    ...
};

(3)

class Mystery                       //Line 1
{
    ...
    friend operator+ (Mystery);         //Line 2
    //Overload the binary operator +
    ...
};
  • 1
    нет константных ссылок, не нужно быть членом, нет возвращаемого значения
  • 1
    Бинарные операторы, такие как <= и +, обычно перегружаются как операторы, не являющиеся членами, и лучше объявить аргументы как константные ссылки.
Показать ещё 1 комментарий
Теги:
operator-overloading

3 ответа

1

Я постараюсь быть немного более основательным, чем ответы до сих пор:

(1)

bool operator <= (Mystery);     //Line 2
  1. Константная корректность для invocant. Оператор <= не должен модифицировать экземпляр, на который он вызывается, и должен указывать, что это не делает const модификатор:

    bool operator <= (Mystery) const;
    
  2. Все остальные предположили, что правильный аргумент должен быть передан ссылкой const, но здесь это зависит от того, что содержит класс. Номера обычно передаются по значению, и если в Mystery содержится только один член примитивного типа и имеет конструктор по умолчанию или встроенный экземпляр, может быть уместно передать значение. При передаче по значению аргумент, очевидно, не может быть изменен, поэтому вам не нужно заботиться о const. Применяется также ко всем дополнительным случаям. Использование ссылки const

    bool operator <= (Mystery const &) const;
    

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

  3. Если класс имеет любые конструкторы, подходящие для преобразования типов (operator+ конструкторы одиночных аргументов из разных типов), оператор должен быть перегружен как функция, не operator+ членом (например, operator+ в случае (3)).

    Это связано с тем, что оператор non-member operator<= будет найден, если аргументы просто преобразуются в Mystery, а оператор-член будет найден только в том случае, если левым оператором является Mystery или производный тип.

    Перегруженные операторы рассматриваются только в том случае, если хотя бы один аргумент является определяемым пользователем типом, то есть компилятор не будет рассматривать bool operator<=(Mystery, Mystery) для аргументов типа (int, int) даже если существует Mystery::Mystery(int), который сделает его жизнеспособным преобразованием. Тем не менее, он будет рассматривать оператор, не являющийся членом для списка аргументов (int, Mystery) то время как он не будет рассматривать оператор bool Mystery::operator<<(Mystery) const для этого.

bool Mystery::<=(Mystery rightObj)    //Line 3

Отсутствует ключевое слово operator.

bool Mystery::operator<=(Mystery rightObj)

(2)

bool operator <= (Mystery, Mystery);  //Line 2

Неверная подпись. operator<= принимает 2 аргумента, один из них является invocant, и поэтому ему нужен только один явный аргумент.

(3)

friend operator+ (Mystery);         //Line 2

Это относится к operator+.

  1. Поскольку operator+ также является двоичным оператором, ему нужны два аргумента.

  2. Оператору + нужен тип возврата. Тип возвращаемого типа обычно должен быть новым экземпляром (т.е. возвратом по значению) класса аргументов.

Функции, не являющиеся членами, не имеют модификатора trailing const, поскольку они не имеют invocant. Аргументы должны передаваться либо по значению, либо по ссылке const в зависимости от содержимого класса:

friend Mystery operator+ (Mystery, Mystery);
friend Mystery operator+ (Mystery const &, Mystery const &);

Ключевое слово friend появляется только при объявлении внутри класса, чтобы предоставить функции доступа к ним частным членам. Вне класса (например, в определении) это просто:

Mystery operator+ (Mystery, Mystery);
Mystery operator+ (Mystery const &, Mystery const &);
0

Случай (1) Ошибка: ожидаемый оператор идентификатора

В строке 3 отсутствует operator Keyword

bool Mystery::operator<=(const Mystery& rightObj)    //Line 3
{
  ...
}

Случай (2) Ошибка: слишком много параметров для реляционного оператора

Реляционный оператор как перегрузка функции-члена должен иметь только один параметр

bool operator <= (const Mystery&);  //Line 2

Случай (3)

Явный тип возвращаемого значения отсутствует

friend Mystery operator+ (const Mystery&);         //Line 2

Другие nitpicks

  1. Если функция не должна мутировать аргумент, сделайте ее ссылкой на константу.
  • 0
    Ну, функция, принимающая значение (как в вопросе), также не может изменить свой аргумент. Или, скорее, он может внутренне изменить свою копию, как ему угодно, но это не влияет на значение в вызывающей стороне.
  • 0
    Тем не менее, инвокант всегда передается по ссылке, поэтому для него требуется постоянная корректность.
Показать ещё 2 комментария
0

bool operator <= (Mystery);
правый объект должен быть константной ссылкой.

bool Mystery::<=(Mystery rightObj)
Неправильный синтаксис должен быть:
bool Mystery::operator <=(const Mystery& rightObj)

bool operator <= (Mystery, Mystery); Оператор - только один параметр - ошибка

friend operator+ (Mystery); Попытка сделать глобальным operator+ другом, должна использовать глобальную область действия "::". Глобальным операторам требуется 2 входа, а не один. Используйте константную ссылку. Оператор также должен вернуть ссылку на "это".

Mystery& operator+(const Mystery& lhs, const Mystery& rhs);

  • 0
    Не забывайте про левый боковой объект!
  • 0
    Верно .... исправлено
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню