下面这段代码很简单啊但是结果好奇怪,出现四次构造函数却出现五次析构函数!!!
请高手帮忙看看啊!!!!!
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();}
请高手帮忙看看啊!!!!!
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();}
complex c1(1,1); //1构造
c1.show();
complex c2; //2构造
c2.show();
c2=c1+(complex)3; //3构造 +号4构造
c2.show();五次析构函数就不清楚了
这条语句发生了三次构造,一次是拷贝构造,由return t;引致,没有显示出来。如果你想看到构造和析构一样多的话,加入这代码:
complex(const complex& c):real(c.real),image(c.image)
{cout<<"calling constructor..."<<endl;}
《深度探索C++对象模型》说得很清楚!
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
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();}
#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();}
《Effective C++ 中文版》 候捷 翻译 Scott Meyers 著
那里面写的非常不错。 49.8人民币
不加引用返回的时候有调用了一次拷贝构造函数,加了引用直接返回产生的临时对象你得搞清楚一次构造必然对应一次析钩,不可能出现四次构造五次析钩