Я знаю, что могу ответить на этот вопрос легко для меня путем генерирования код и видеть, компилирует ли он. Но так как я не мог найти подобный вопрос, я думал, что это - знание, которое стоит совместно использовать. Скажите, что я перегружаюсь + оператор для 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 + перегрузки для + оператор), но все еще могут написать легко код чтения с помощью основных арифметических операторов. Так, я получу желаемое поведение?
Каноническая форма реализации 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 ::
либо не нужен, либо даже неверен.)
Да, вы можете перегрузить такие операторы. Но я не уверен, о каком «корпусе переключателя» вы имеете в виду. Вы можете жить с одной перегрузкой, если у вас есть конвертирующий конструктор
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 с любой стороны с минимальными затратами кода.
Да.
Эти операторные функции представляют собой обычные функции со специальными именами operator @
. Нет никаких ограничений, что они не могут быть перегружены. Фактически, оператор <<
, используемый iostream, является оператором с несколькими перегрузками.