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