+=运算符重载
来源:互联网 发布:js 增加option 编辑:程序博客网 时间:2024/05/17 23:48
要实现上面的需求,我们只需重载 operatpr+= 操作符即可,下面就是一个简单的示例,可以实现 c1+=c2的需求。
#include <iostream>using namespace std;class Complex{public: Complex(float x, float y) :_x(x), _y(y) { cout << "Complex contructor" << endl; } void display() { cout << "(x = " << _x << ", y = " << _y << ")" << endl; } void operator+=(Complex another) { this->_x += another._x; this->_y += another._y; }private: float _x; float _y;};int main(int argc, char* argv[]){ Complex c1(10.0, 15.0); Complex c2(20.0, 25.0); c1.display(); c2.display(); c1 += c2; c1.display(); return 0;}
运算的结果如下:
(x = 10, y = 15) // c1(x = 20, y = 25) // c2(x = 30, y = 40) // c1 + c2
上面的代码实现了我们的简单+=需求,还有很多细节的地方没有考虑到,并且程序的运行效率也是有待优化的。首先我们先考虑以下情况。
C++关键字int类型创建的对象可以实现连等的操作,比如下面的例子;
int a = 10, b = 20, c = 30;a += b += c;cout << a << endl;cout << b << endl;cout << c << endl;
最终结果
605030
该表达式是从右向左依次执行的,首先计算 b+=c,结果b=50,c没有变动。然后计算a+=b,a=60,b=50。
如果我们要让类实现这样的功能,使用上面我们写好的代码可以成功吗?我们不妨测试一下,将main函数中的代码修改为如下的样子:
int main(int argc, char* argv[]){ Complex c1(10, 0); Complex c2(20, 0); Complex c3(30, 0); c1 += c2 += c3; c1.display(); c2.display(); c3.display(); return 0;}
此时再编译程序,你会发现出现了错误:
二进制“+=”: 没有找到接受“void”类型的右操作数的运算符(或没有可接受的转换),这句话是什么意思呢?我们分析一下程序的运算过程,一样是从右向左,相当于
c1.operator+=(c2.operator+=(c3))
首先是c2+=c3,在函数内部,我们给分别修改了 this->_x 和 this->_y的值,但此时你会发现,处理函数并没有返回任何值,这让接下来的 c1 与谁相加呢?这种情况下我们是不是要返回一个 Complex 的对象,才能使 c1 正常的与其相加,再次相加的过程会重复进入 operator+= 的重载函数中。所以,重载函数应该修改为如下的样子。
// 修改返回值为 Complex 对象Complex operator+=(Complex another){ this->_x += another._x; this->_y += another._y; // 将 this 指针解引用后返回 return *this;}
如上修改后,代码成功的运行了,我们得到了想要的结果:
(x = 60, y = 0) // c1.operator(c2.operator(c3))(x = 50, y = 0) // c2.operator(c3)(x = 30, y = 0) // c3
解决这个问题,我们只修改了函数的返回值,并在函数内部返回了解引用后的*this对象。这样就实现了连等的操作。接下来,我们继续考虑这样的情况。
在基础数据类型中,是允许出现这样的表达式的:
int a = 10, b = 20, c = 30;(a += b) += c;cout << a << endl;cout << b << endl;cout << c << endl;
运算的过程是,a首先与b结合,得到结果a=30,b未改变。随后得出的结果再与c结合,a+=c,结果a=60,c未改变。同样的案例,我们再次应用到我们自己重载的函数中试一下。将程序修改为如下的所示:
Complex c1(10, 0);Complex c2(20, 0);Complex c3(30, 0);(c1 += c2) += c3;c1.display();c2.display();c3.display();
运算后得出的结果是:
(x = 30, y = 0) // c1(x = 20, y = 0) // c2(x = 30, y = 0) // c3
这与上面基础数据类型运算出来的结果不一样啊,应该是 60 20 30 啊,怎么会变成这样的数据呢?我们细心来分析一下上面的案例,首先c1与c2先结合,c1+=c2后我们返回了*this,但返回值大家请注意,返回值并不是*this的引用,而是一份临时的对象与c3做了相加操作,最后临时对象销毁,而c1自身并没有参与到运算当中。所以最终得出的结果就是 30 20 30。那么想解决这个问题也非常简单,只需将返回值修改为Complex的引用即可,这样在c1与c2结合后得出的对象才是真正的c1,再与c3结合得出最终结果。
// 修改返回值为 Complex 对象的引用Complex& operator+=(Complex another){ this->_x += another._x; this->_y += another._y; // 将 this 指针解引用后返回 return *this;}
运算结果:
(x = 60, y = 0) //(c1 += c2) += c3(x = 20, y = 0) //c2(x = 30, y = 0) //c3
至此,+=运算符的重载我们就实现完毕了,几乎所有基本数据类型能实现的需求我们都实现了一遍,像-= *= /=运算符都与其类似。只需要按部就班的一步一步测试下来即可实现。
- 重载=运算符
- +=运算符重载
- 重载“=”运算符
- 重载运算符=
- 十九、运算符重载(三)String类的改进实现、[]运算符重载、+运算符重载、+=运算符重载、<<运算符重载、>>运算符重载
- == 运算符重载
- C++ 运算符重载 =
- 关于=运算符重载
- 重载赋值运算符=
- C++运算符重载+、-、=
- 运算符重载 [++,--,+,<<; &&,||(不可重载)]
- 重载之运算符重载
- C++读书笔记之 赋值运算符= 重载 前缀自减运算符--重载 求负运算符- 重载
- C#==>运算符重载
- 重载运算符 == C#
- Python ==运算符重载
- vector<tmplate> == 运算符重载
- =号运算符的重载
- 【IMWeb训练营作业】Todo Liss试手制作
- 【LeetCode】Hamming Distance
- css3 box-sizing属性
- HTTP常见状态码
- Android 动画--补间动画(Tween Animation)
- +=运算符重载
- 实时更新的天气预报页面
- 《深入理解java虚拟机》-java堆溢出笔记
- HDU2807
- java删除数组中重复元素
- 单列集合set中实现类HashSet和TreeSet
- Gym
- Nginx的反向代理及负载均衡
- ssm开发webService