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*/
我想这样做的原因是我正在构建一个我想要尽可能优化的类。性能是我最关心的问题。因此,在运算符+重载函数内部进行强制转换和使用 switch case 不是一种选择。如果您注意到的话,我将这两个重载都内联了。让我们假设编译器确实内联了我的重载,然后在编译时就预先确定了将运行哪些代码,并且我保存了对函数的调用(通过内联)+一个复杂的 switch case 场景(实际上,将会有+ 运算符的 5+ 重载),但我仍然能够使用基本算术运算符编写易于阅读的代码。 那么,我会得到想要的行为吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的。
这些运算符函数只是具有特殊名称
operator@
的普通函数。没有限制它们不能超载。事实上,iostream使用的<<
运算符是一个具有多个重载的运算符。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.实现
operator+()
的规范形式是一个基于operator+=()
的自由函数,当您拥有+
时,您的用户会期望它。+=
更改其左侧参数,因此应该是成员。+
对称地处理其参数,因此应该是一个自由函数。像这样的事情应该做:(
请注意,使用其类定义定义的成员函数是隐式
内联
。另请注意,在MyClass
内,前缀MyClass::
要么不需要,要么甚至是错误的。)The canonical form of implementing
operator+()
is a free function based onoperator+=()
, 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:
(Note that member functions defined with their class' definition are implicitly
inline
. Also note, that withinMyClass
, the prefixMyClass::
is either not needed or even wrong.)是的,您可以像这样重载运算符。但我不确定你指的“开关盒”是什么。如果你有一个转换构造函数,你就可以接受一个重载,
根本不需要任何开关。如果“MyClass”在逻辑上代表一个数字,则这是合格的。
请注意,您应该通过非成员函数重载这些运算符。在您的代码中
5 + c1
不起作用,因为没有运算符将 int 作为左侧。下面的代码可以工作现在,如果保留转换构造函数,则可以以最小的代码开销在任一侧添加 int 。
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
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 workNow if you keep the converting constructor you can add the int by either side with minimal code overhead.