我知道我可以通过生成代码轻松地回答这个问题并查看它是否编译。但由于我找不到类似的问题,我认为这是值得分享的知识。 假设我正在为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*/
我想这样做的原因是我正在构建一个我希望尽可能优化的类。性能是我最关心的问题。因此,在操作员+重载功能内部铸造和使用开关盒不是一种选择。我注意到,我把内插的重载都做了。让我们假设编译器确实内联我的重载,然后在编译时预先确定哪些代码将运行,并且我将调用保存到一个函数(通过内联)+一个复杂的开关案例场景(实际上,将会有+运算符的5+重载,但我仍然能够使用基本算术运算符轻松编写读取代码。 那么,我会得到理想的行为吗?
答案 0 :(得分:10)
是。
这些运算符函数只是具有特殊名称operator@
的普通函数。他们不能超载是没有限制的。事实上,iostream使用的<<
运算符是一个具有多个重载的运算符。
答案 1 :(得分:9)
实施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
}
(请注意,使用其类定义定义的成员函数是隐式inline
。另请注意,在MyClass
内,前缀MyClass::
不需要甚至是错误的。)< / p>
答案 2 :(得分:2)
是的,您可以像这样重载运算符。但我不确定你指的是什么“切换案例”。如果您有转换构造函数,则可以使用一个重载
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。