博客内容为本人原创,做为平时学习笔记用,本人刚刚接触C++,水平有限,希望各位多批评!
编译环境为VS;
先上测试代码:
#includeusing namespace std; class A { public: int s; A(int k) { s = k; cout << k << "A running" << endl; } //有参 A(const A & p) { cout << "copy" < s = p.s; } //拷贝 ~A() { cout << s << "A del" << endl; } //析构 }; A operator+(A p1,A p2) { A temp(0); temp.s = p1.s + p2.s; return temp; } int main() { A s1(1); A s2(2); A s3(3); A s4 = s1 + s2 + s3; cout << s1.s << endl; cout << s2.s << endl; cout << s3.s << endl; cout << s4.s << endl; return 0; }
运行结果为:
1. 1A running
2. 2A running
3. 3A running
4. copy3
5. copy2
6. copy1
7. 0A running
8. copy3
9. 3A del
10. 1A del
11. 2A del
12. 0A running
13. copy6
14. 6A del
15. 3A del
16. 3A del
17. 1
18. 2
19. 3
20. 6
21. 6A del
22. 3A del
23. 2A del
24. 1A del
接下来对结果逐行分析:
前三行调用有参构造函数,按顺序生成s1,s2,s3入栈;
| s3 |
| s2 |
| s1 |
接下来三行可以看出,在调用重载运算符时,首先要从右往左逐一进行拷贝,之后再进行函数内部的运算,此时内部栈的情况为:
| s1(拷贝) |
| s2(拷贝) |
| s3(拷贝) |
第七行函数内部生成了temp对象(0A running),入栈;
| temp |
| s1(拷贝) |
| s2(拷贝) |
| s3(拷贝) |
在函数执行完成时,函数先复制了一份temp的拷贝(第八行结果为3,这里也可以看出,调用时是先从右向左复制实参,而计算的顺序是从左向右的,即先计算s1 + s2),接着调用析构函数,temp、s1(拷贝)、s2(拷贝)出栈(第九至十一行,析构顺序为3,1,2可以证明这一点);
到现在我们手里还剩下temp(拷贝),其值为3,入栈,这是s1 + s2的结果,我们现在计算 "temp(拷贝)+ s3”,此时栈情况为
| temp(拷贝) |
| s3(拷贝) |
这次计算的过程就跟上次差不多了,还是先构造一个对象(12行0A running,新的对象入栈,其计算后的值为temp(拷贝)的3加上s3的3,结果为6)
| temp(第二次计算) |
| temp(拷贝) |
| s3(拷贝) |
因此在第二次计算完成后,函数要先拷贝好temp(第二次计算),即第13行的copy6,然后从栈顶依次调用析构函数,即14-16行输出结果,这时栈空,我们带着最终的计算结果temp(最终)返回到主函数(注意:temp(最终)的s是个拷贝值);
这时temp(最终)的内容被复制给了s4;
17-20行我们依次输出对象的s值,结果与预想的是一样的;
此时栈(最开始的那个栈)情况为
| s4 |
| s3 |
| s2 |
| s1 |
主函数运行完,依次从栈顶调用析构函数,结果即6 3 2 1。
如有本人理解错误或表述不当之处,还请多多批评指教!



