下面这段代码很简单啊但是结果好奇怪,出现四次构造函数却出现五次析构函数!!!
请高手帮忙看看啊!!!!!
vc6下通过#include<iostream.h>class complex
{
float real;
float image;
public:
complex(float r=0,float i=0)
{real=r;image=i;cout<<"calling constructor..."<<endl;}
~complex()
{cout<<"calling disconstructor..."<<endl;}
void show()
{cout<<"real:"<<real<<" "<<"image:"<<image<<endl;}
complex operator+(complex&c)
{
        complex t;
        t.real=real+c.real;
        t.image=image+c.image;
return t;
}
};
void main()
{
complex c1(1,1);
c1.show();
complex c2;
c2.show();
c2=c1+(complex)3;
c2.show();}

解决方案 »

  1.   


    complex c1(1,1);  //1构造
    c1.show();
    complex c2;        //2构造
    c2.show();
    c2=c1+(complex)3;   //3构造   +号4构造
    c2.show();五次析构函数就不清楚了
      

  2.   

    c2=c1+(complex)3;
    这条语句发生了三次构造,一次是拷贝构造,由return t;引致,没有显示出来。如果你想看到构造和析构一样多的话,加入这代码:
    complex(const complex& c):real(c.real),image(c.image) 
    {cout<<"calling constructor..."<<endl;}
      

  3.   

    同意楼上的,operator = 会调用Copy Constructor操作。
    《深度探索C++对象模型》说得很清楚!
      

  4.   

    看了它,全明白:
    39:   void main()
    40:   {
    004013C0   push        ebp
    004013C1   mov         ebp,esp
    004013C3   push        0FFh
    004013C5   push        offset __ehhandler$_main (00402b4b)
    004013CA   mov         eax,fs:[00000000]
    004013D0   push        eax
    004013D1   mov         dword ptr fs:[0],esp
    004013D8   sub         esp,6Ch
    004013DB   push        ebx
    004013DC   push        esi
    004013DD   push        edi
    004013DE   lea         edi,[ebp-78h]
    004013E1   mov         ecx,1Bh
    004013E6   mov         eax,0CCCCCCCCh
    004013EB   rep stos    dword ptr [edi]
    41:       complex c1(1,1);
    004013ED   push        3F800000h
    004013F2   push        3F800000h
    004013F7   lea         ecx,[ebp-14h]
    004013FA   call        @ILT+5(complex::complex) (0040100a)
    004013FF   mov         dword ptr [ebp-4],0
    42:       c1.show();
    00401406   lea         ecx,[ebp-14h]
    00401409   call        @ILT+10(complex::show) (0040100f)
    43:       complex c2;
    0040140E   push        0
    00401410   push        0
    00401412   lea         ecx,[ebp-1Ch]
    00401415   call        @ILT+5(complex::complex) (0040100a)
    0040141A   mov         byte ptr [ebp-4],1
    44:       c2.show();
    0040141E   lea         ecx,[ebp-1Ch]
    00401421   call        @ILT+10(complex::show) (0040100f)
    45:       c2=c1+(complex)3;
    00401426   push        0
    00401428   push        40400000h
    0040142D   lea         ecx,[ebp-24h]
    00401430   call        @ILT+5(complex::complex) (0040100a)
    00401435   mov         dword ptr [ebp-30h],eax
    00401438   mov         eax,dword ptr [ebp-30h]
    0040143B   mov         dword ptr [ebp-34h],eax
    0040143E   mov         byte ptr [ebp-4],2
    00401442   mov         ecx,dword ptr [ebp-34h]
    00401445   push        ecx
    00401446   lea         edx,[ebp-2Ch]
    00401449   push        edx
    0040144A   lea         ecx,[ebp-14h]
    0040144D   call        @ILT+20(complex::operator+) (00401019)
    00401452   mov         dword ptr [ebp-38h],eax
    00401455   mov         eax,dword ptr [ebp-38h]
    00401458   mov         ecx,dword ptr [eax]
    0040145A   mov         edx,dword ptr [eax+4]
    0040145D   mov         dword ptr [ebp-1Ch],ecx
    00401460   mov         dword ptr [ebp-18h],edx
    00401463   lea         ecx,[ebp-2Ch]
    00401466   call        @ILT+0(complex::~complex) (00401005)
    0040146B   mov         byte ptr [ebp-4],1
    0040146F   lea         ecx,[ebp-24h]
    00401472   call        @ILT+0(complex::~complex) (00401005)
    46:       c2.show();
    00401477   lea         ecx,[ebp-1Ch]
    0040147A   call        @ILT+10(complex::show) (0040100f)
    47:       return;
    0040147F   mov         byte ptr [ebp-4],0
    00401483   lea         ecx,[ebp-1Ch]
    00401486   call        @ILT+0(complex::~complex) (00401005)
    0040148B   mov         dword ptr [ebp-4],0FFFFFFFFh
    00401492   lea         ecx,[ebp-14h]
    00401495   call        @ILT+0(complex::~complex) (00401005)
    48:   }
    0040149A   mov         ecx,dword ptr [ebp-0Ch]
    0040149D   mov         dword ptr fs:[0],ecx
    004014A4   pop         edi
    004014A5   pop         esi
    004014A6   pop         ebx
    004014A7   add         esp,78h
    004014AA   cmp         ebp,esp
    004014AC   call        _chkesp (00401804)
    004014B1   mov         esp,ebp
    004014B3   pop         ebp
    004014B4   ret
      

  5.   

    原因在这:
    complex operator+(complex&c)
    {
            complex t;
            t.real=real+c.real;
            t.image=image+c.image;
    return t;
    }
    这个运算符重载函数的返回值是对象拷贝,而不是对象的引用或地址,所以多出一个析构函数。返回值修改为complex&即可!修正后的源代码如下:
    #include<iostream.h>class complex
    {
    float real;
    float image;
    public:
    complex(float r=0,float i=0)
    {real=r;image=i;cout<<"calling constructor..."<<endl;}
    ~complex()
    {cout<<"calling disconstructor..."<<endl;}
    void show()
    {cout<<"real:"<<real<<" "<<"image:"<<image<<endl;}
    complex& operator+(complex&c)
    {
            complex t;
            t.real=real+c.real;
            t.image=image+c.image;
    return t;
    }
    };
    void main()
    {
    complex c1(1,1);
    c1.show();
    complex c2;
    c2.show();
    c2=c1+(complex)3;
    c2.show();}
      

  6.   

    同意楼上!我的研究结果源代码如下:
    #include "StdAfx.h"
    #include <iostream.h>class complex
    {
    float real;
    float image;
    public:
    complex(float r=0,float i=0)
    {real=r;image=i;cout<<"("<<real<<","<<image<<")"<<"calling constructor..."<<endl;}
    ~complex()
    {cout<<"("<<real<<","<<image<<")"<<"calling disconstructor..."<<endl;}
    void show()
    {cout<<real<<" +i*"<<image<<endl;}
    complex& operator+(complex& c)
    {
            complex t;
            t.real=this->real+c.real;
            t.image=this->image+c.image;
    return t;
    }
    complex& operator=(const complex& c)
    {
    this->real=c.real;
    this->image=c.image;
    return *this;
    }
    };
    void main()
    {
    complex c1(1,1);
    c1.show();
    complex c2;
    c2.show();
    // c2=c1+(complex)3;
    c2=c1+complex(3);
    c2.show();}
      

  7.   

    关于析构,构造的问题,强烈建议看看:
    《Effective C++ 中文版》 候捷  翻译  Scott Meyers 著
    那里面写的非常不错。 49.8人民币
      

  8.   

    To shiluoye(菜鸟中的菜鸟)那能不能详细解释一下为什么加了引用就真确了呢?
    不加引用返回的时候有调用了一次拷贝构造函数,加了引用直接返回产生的临时对象你得搞清楚一次构造必然对应一次析钩,不可能出现四次构造五次析钩