问题
I know I can answer this question easily for myself by generatin the code and see if it compiles. But since I couldn't find a similar question, I thought it's knowledge worth sharing. Say I am overloading the + operator for MyClass. Can I overload it multiple times. Different overload for different types. Like this:
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*/
The reason I want to do this is that I am building a class that I want to be as optimized as possible. Performance is the biggest concern for me here. So casting and using switch case inside the operator + overloaded function is not an option. I f you'll notice, I made both the overloads inline. Let's assume for a second that the compiler indeed inlines my overloads, then it is predetermined at compile time which code will run, and I save the call to a function (by inlining) + a complicated switch case scenario (in reality, there will be 5+ overloads for + operator), but am still able to write easily read code using basic arithmetic operators. So, will I get the desired behavior?
回答1:
The canonical form of implementing operator+()
is a free function based on operator+=()
, which your users will expect when you have +
. +=
changes its left-hand argument and should thus be a member. The +
treats its arguments symmetrically, and should thus be a free function.
Something like this should do:
//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
}
(Note that member functions defined with their class' definition are implicitly inline
. Also note, that within MyClass
, the prefix MyClass::
is either not needed or even wrong.)
回答2:
Yes.
These operator functions are just ordinary functions with the special names operator@
. There's no restriction that they cannot be overloaded. In fact, the <<
operator used by iostream is an operator with multiple overloads.
回答3:
Yes, you can overload operators like this. But I'm not sure what "switch case" you are referring to. You can live with one overload if you have a converting constructor
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
}
...
};
No switch is needed at all. This is eligible if "MyClass" logically represents a number.
Notice that you should overload these operators by non-member functions. In your code 5 + c1
would not work, because there is no operator that takes an int as left hand side. The following would work
inline const MyClass operator+(const MyClass &lhs, const MyClass &rhs) {
// ...
}
Now if you keep the converting constructor you can add the int by either side with minimal code overhead.
来源:https://stackoverflow.com/questions/3123699/c-multiple-operator-overloads-for-the-same-operator