我应该使用c++操作符重载的哪个变体?,为什么
Which variation of C++ Operator Overloading should I use? And, why?
这里给出了加法运算符(+)的3种重载形式。
我应该使用哪个变体,为什么?
class MyClass {
int myInteger;
double myDouble;
public:
MyClass(int i, double d) {
myInteger = i;
myDouble = d;
}
// Variation - 1
//--------------
MyClass operator +(MyClass rhsObj) {
return MyClass(this->myInteger + rhsObj.myInteger, this->myDouble + rhsObj.myDouble);
}
// Variation - 2
//--------------
MyClass &operator +(MyClass &rhsObj) {
rhsObj.myInteger = this->myInteger + rhsObj.myInteger;
rhsObj.myDouble = this->myDouble + rhsObj.myDouble;
return rhsObj;
}
// Variation - 3
//--------------
MyClass &operator +(MyClass &rhsObj) {
this->myInteger = this->myInteger + rhsObj.myInteger;
this->myDouble = this->myDouble + rhsObj.myDouble;
return *this;
}
};
int main() {
MyClass objOne(10, 10.5);
MyClass objTwo(20, 20.5);
MyClass objThree = objOne + objTwo;
}
赋值操作符(=)应该是什么情况?它应该使用哪种变体?
看你需要什么
首先,关于你的版本-显然
- "Variation - 1"创建新对象,不触及两个操作数。
- "Variation - 2"将结果存储在第二个操作数
- "Variation - 3"将结果存储在"this"的第一个操作数中。
最有可能的是,变异- 1是最受欢迎的。
为什么?因为有副作用。如果你看到这样的表达式:
a = b + c;
无论a
, b
和c
的类型是什么,你会怎么想?我认为,a
是b
和c
的总和,而b
和c
是不变的,我的意思是-与旧值。
假设,例如:
a = 5;
b = 6;
c = a + b;
你认为a
或b
在求和后会变成11
吗?当然,不能为int
重载operator+
,但这只是一个简单直观的例子。
一个性能改进:在你的变体1中,而不是
MyClass operator+(MyClass rhsObj)
我会用
MyClass operator+(const MyClass& rhsObj)
这样你将避免一个额外的复制+你将告诉"客户端",使用你的代码,你不改变rhsObj
,而只是使用它的值。
你真的需要one和three的变化。
MyClass
的用户将期望它遵循最小惊奇原则,并且永远不会期望看到右侧由于加法而被修改。使用const
将加强这一点,也将作为文档。如果您希望修改左侧,请使用+=
。像这样:
// Plus: Modify neither the left nor the right
//--------------
MyClass operator +(const MyClass& rhsObj) const
{
return MyClass(myInteger + rhsObj.myInteger, myDouble + rhsObj.myDouble);
}
// Increment: Modify the left
//--------------
MyClass& operator +=(const MyClass& rhsObj)
{
myInteger += rhsObj.myInteger;
myDouble += rhsObj.myDouble;
return *this;
}
演示:http://ideone.com/8oarA
这三个+
之间有细微的差别
第一个变体:
// Variation - 1
//--------------
MyClass operator+(MyClass rhsObj)
{
return MyClass(this->myInteger + rhsObj.myInteger, this->myDouble + rhsObj.myDouble);
}
接受MyClass
的对象作为输入,这意味着将rhsObj
的副本传递给+
,而原始对象rhsObj
保持不变。这个重写返回一个新创建的MyClass
对象。
第二个变体:
// Variation - 2
//--------------
MyClass & operator+(MyClass & rhsObj)
{
rhsObj.myInteger = this->myInteger + rhsObj.myInteger;
rhsObj.myDouble = this->myDouble + rhsObj.myDouble;
return rhsObj;
}
以对rhsObj
的引用作为输入,并在方法中更新rhsObj
。
最后一次变奏
// Variation - 3
//--------------
MyClass & operator+(MyClass & rhsObj)
{
this->myInteger = this->myInteger + rhsObj.myInteger;
this->myDouble = this->myDouble + rhsObj.myDouble;
return *this;
}
也以对rhsObj
的引用作为参数,但是rhsObj
在方法内部没有被修改。相反,调用+
的MyClass
对象被更新。
从概念上讲,您希望返回一个新的对,因此在您的情况下,第一个变体可能更好。
或者你想返回其中一个参数,但是我发现操作符的名称混淆了。对于第三个变体,+=
可能会更好。
我认为变异1将是最好的,主要有一个原因:如果你只有语句lhs + rhs;
,你会期望/希望lhs
或rhs
被修改吗?我知道在大多数(所有?)情况下我可能不会这么做。
因此排除了变型2和3
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在全局范围内使用"extern int a"似乎不行?
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 为什么会发生堆损坏
- 为什么使用 "this" 指针调用派生成员函数?
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么比较运算符如此快速
- 为什么 Serial.println(<char[]>);返回随机字符?
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 为什么不;名字在地图上是按顺序排列的吗
- 我的字符计数代码计算错误.为什么
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 为什么 std::unique 不调用 std::sort?
- 既然存在危险,为什么项目要使用-I include开关
- 为什么在运行时没有向我们提供有关分段错误的更多信息?