C++ несколько перегрузок оператора для того же оператора

Я знаю, что могу ответить на этот вопрос легко для меня путем генерирования код и видеть, компилирует ли он. Но так как я не мог найти подобный вопрос, я думал, что это - знание, которое стоит совместно использовать. Скажите, что я перегружаюсь + оператор для MyClass. Действительно ли я могу перегрузить его многократно. Другая перегрузка для различных типов. Как это:

class MyClass{
...
inline const MyClass operator+(const MyClass &addend) const {
    cout<<"Adding MyClass+MyClass"<<endl;
    ...//Code for adding MyClass with MyClass
}
inline const MyClass operator+(const int &addend) const {
    cout<<"Adding MyClass+int"<<endl;
    ...//Code for adding MyClass with int
}
...
};
int main(){
    MyClass c1;
    MyClass c2;
    MyClass c3 = c1 + c2; 
    MyClass c4 = c1 + 5;
}
/*Output should be:
  Adding MyClass+MyClass
  Adding MyClass+in*/

Причина, которую я хочу сделать, это - то, что я создаю класс, что я хочу быть максимально оптимизированным. Производительность является самым большим беспокойством обо мне здесь. Так бросая и с помощью случая переключателя в операторе + перегруженная функция не является опцией. Я f, который Вы заметите, я сделал обоих перегрузками встроенный. Давайте предположим в течение секунды, что компилятор действительно встраивает мои перегрузки, затем он предопределяется во время компиляции, какой код будет работать, и я сохраняю вызов к функции (путем встраивания) + сложный вариант развития событий переключателя (в действительности, будет 5 + перегрузки для + оператор), но все еще могут написать легко код чтения с помощью основных арифметических операторов. Так, я получу желаемое поведение?

10
задан eladidan 26 June 2010 в 13:06
поделиться

3 ответа

Каноническая форма реализации operator + () - это бесплатная функция, основанная на operator + = () , которую ваши пользователи будут ожидать, когда у вас будет + . + = изменяет свой левый аргумент и, таким образом, должен быть членом. + обрабатывает свои аргументы симметрично и, следовательно, должна быть свободной функцией.

Должно быть что-то вроде этого:

//Beware, brain-compiled code ahead!
class MyClass {
public:
    MyClass& operator+=(const MyClass &rhs) const
    {
      // code for adding MyClass to MyClass
      return *this;
    }
    MyClass& operator+=(int rhs) const
    {
      // code for adding int to MyClass
      return *this;
    }
};


inline MyClass operator+(MyClass lhs, const MyClass& rhs) {
  lhs += rhs;
  return lhs;
}
inline MyClass operator+(MyClass lhs, int rhs) {
  lhs += rhs;
  return lhs;
}
// maybe you need this one, too
inline MyClass operator+(int lhs, const MyClass& rhs) {
  return rhs + lhs; // addition should be commutative
}

(Обратите внимание, что функции-члены, определенные с помощью определения их класса, неявно встроены в . Также обратите внимание, что в MyClass префикс ] MyClass :: либо не нужен, либо даже неверен.)

9
ответ дан 3 December 2019 в 17:57
поделиться

Да, вы можете перегрузить такие операторы. Но я не уверен, о каком «корпусе переключателя» вы имеете в виду. Вы можете жить с одной перегрузкой, если у вас есть конвертирующий конструктор

class MyClass{
...
// code for creating a MyClass out of an int
MyClass(int n) { ... }
...
inline const MyClass MyClass::operator+(const MyClass &addend) const {
    cout<<"Adding MyClass+MyClass"<<endl;
    ...//Code for adding MyClass with MyClass
}
...
};

Никакой переключатель не нужен вообще. Это допустимо, если «MyClass» логически представляет собой число.

Обратите внимание, что вы должны перегрузить эти операторы функциями, не являющимися членами. В вашем коде 5 + c1 не будет работать, потому что нет оператора, который принимает int как левую часть. Следующее будет работать

inline const MyClass operator+(const MyClass &lhs, const MyClass &rhs) {
  // ...
}

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

2
ответ дан 3 December 2019 в 17:57
поделиться

Да.


Эти операторные функции представляют собой обычные функции со специальными именами operator @ . Нет никаких ограничений, что они не могут быть перегружены. Фактически, оператор << , используемый iostream, является оператором с несколькими перегрузками.

11
ответ дан 3 December 2019 в 17:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: