为何执行了三次析构

为什么执行了三次析构?

#include <iostream>
using namespace std;
class A
{
private:
int data;
public:
A(){cout<<"默认构造"<<endl;}
A(int i):data(i){ cout<<"参数构造"<<data<<endl;}
A(const A &b){ data=b.data; cout<<"拷贝构造"<<data<<endl;}
~A(){ cout<<"析构"<<endl;}
};
A play(A a)
{
return a;
}
int main(void)
{
A temp;
temp=play(5);
return 0;
}


为何执行了三次析构
我只知道会执行两次析构。第一次是play(5)产生对象的析构,第二次是temp的析构,那还有一次的析构是怎么发生的呢?
如果将程序改成A temp=play(5);就会执行两次构造,两次析构,为什么在这种情况下少了一次析构?
------解决思路----------------------
    A temp = play(5);// A(const A &b)
    temp = play(5);//operator=(const A& other)

------解决思路----------------------
#include <iostream>
using namespace std;
class A
{
private:
    int data;
public:
    A(){cout<<"默认构造"<<endl;}
    A(int i):data(i){ cout<<"参数构造"<<data<<endl;}
    A(const A &b){ data=b.data; cout<<"拷贝构造"<<data<<endl;}
    ~A(){ cout<<"析构"<<endl;}
};
A play(A a)
{
    return a; //1.这里return出去以后,这个函数调用完毕会执行第一次析构(那个参数a的)
}
int main(void)
{
    A temp;  //3.这里是最后一次析构
    temp=play(5); //2.这里接收到那个返回的对象用完以后还会调用一次析构
    return 0;
}//程序退出 最后执行main内定义的temp对象的析构,共三次
------解决思路----------------------
构造与析构一一对应
------解决思路----------------------
int main(void)
 {
     A temp;  //1.构造了一个对象temp;
    temp=play(5); //2.首先构造一个临时对象(5)作为 play函数的参数
    return 0;
 }

A play(A a)
 {
     return a;  // 3.在函数play内, 当其返回时构造了一个临时对象作为返回值
}

析构函数与构造函数一一对应。 所以也是三次
------解决思路----------------------
如果将程序改成A temp=play(5);就会执行两次构造,两次析构,为什么在这种情况下少了一次析构?

---少了 A temp的那次默认构造
------解决思路----------------------
编译器会把

A play(A a)
{
return a;
}

这个函数改成成类似于这样

void paly(A& result_, A a)
{
    result.A(a); //这里调用了传说中的拷贝构造函数
}

这里为返回值又构造了一个临时变量,所以出现了三次构造,三次析构
------解决思路----------------------
引用:
Quote: 引用:

编译器会把

A play(A a)
{
return a;
}

这个函数改成成类似于这样

void paly(A& result_, A a)
{
    result.A(a); //这里调用了传说中的拷贝构造函数
}

这里为返回值又构造了一个临时变量,所以出现了三次构造,三次析构


拷贝构造应该是temp=play(5)产生的,就是给temp赋值的时候

这位同学,不好意思,这里我有一点不同意见,temp=play(5),是调用的默认的operator=,拷贝构造,注意它的构造二字,是指类对象在定义的时候调用的,此处你的temp已经构造好了,这只是一个赋值语句。我所说的解释,是我单步调试看的反汇编得出来的,而且我使用了VC和GCC两个编译器得出的答案。关于函数返回值的处理,你也可以看《深度探索C++对象模型这本书》。