c++ 析构函数

编写了一个简单人民币类,然后用主函数验证,创建了三个对象,程序没运行到结束,显示却看到了提前析构,程序如下:/------------------------------... 编写了一个简单人民币类,然后用主函数验证,创建了三个对象,程序没运行到结束,显示却看到了提前析构,程序如下:
/--------------------------------------------------------------
//renminbi.h
//--------------------------------------------------------------
#include<iostream.h>
#include"stdlib.h"
class Renminbi
{
private:
int yuan;
int jiao;
int fen;
static int number;
public:
Renminbi(int y,int j,int f):yuan(y),jiao(j),fen(f) {number++;}

friend ostream& operator<<(ostream& out,const Renminbi & r);
Renminbi operator+(Renminbi & r)const;
Renminbi& operator+=(const Renminbi & r);
~Renminbi()
{cout<<"析构函数"<<"\n";
number--;
cout<<number<<"\n";}
};
int Renminbi::number=0;

//-----------------------------------------------------------------
//Renminbi.cpp
//-----------------------------------------------------------------

Renminbi Renminbi::operator +(Renminbi & r)const
{
Renminbi m(0,0,0);
m.yuan=yuan+r.yuan;
m.jiao=jiao+r.jiao;
m.fen=fen+r.fen;
return m;
}

Renminbi& Renminbi::operator +=(const Renminbi & r)
{
yuan+=r.yuan;
jiao+=r.jiao;
fen+=r.fen;
return *this;
}

ostream& operator<<(ostream& out,const Renminbi & r)
{
if((r.yuan*100+r.jiao*10+r.fen)<0)
out<<"-"<<r.yuan<<"元"<<"-"<<r.jiao<<"角"<<"-"<<r.fen<<"分"<<"\n";
out<<r.yuan<<"元"<<r.jiao<<"角"<<r.fen<<"分"<<"\n";
return out;
}

//--------------------------------------------------------------------
//应用程序
//--------------------------------------------------------------------
int main()
{// 创建对象money,money1,money2
Renminbi money(2,3,45),money1(-1,10,2),money2(0,0,0);
cout<<"the first:"<<money<<"\n";
cout<<"the second:"<<money1<<"\n";
//调用成员函数operator+
money2=money+money1;
cout<<"money2: "<<money2<<"\n";
//调用成员函数operator+=
money+=money1;
cout<<"money+=money1:"<<money<<"\n";

return 0;

}
结果显示如下:显示如下:
the first:2元3角45分
the second:-1元10角2分
析构函数
3
析构函数
2
money2:1元13角47分
money+=money1:1元13角47分
析构函数
1
析构函数
0
析构函数
-1
请大家帮忙分析下为什么程序没结束就开始调用析构函数?
展开
 我来答
luosiyong
2011-05-26 · TA获得超过3256个赞
知道大有可为答主
回答量:1090
采纳率:0%
帮助的人:1626万
展开全部
结果中最后的三次析构好理解,就是main函数中的Renminbi money(2,3,45),money1(-1,10,2),money2(0,0,0);这三个析构。
前面两次析构:
第一次是operator+里面的临时变量,在operator+函数返回的时候,析构。这个临时变量是你在代码中定义的。
第二次是money2=money+money1;这里,money+money1计算的结果会先保存在一个临时变量里面,再赋值给money2。赋值完毕的时候,这个临时变量析构。这个临时变量是系统执行+操作时候产生的。
注释掉money2=money+money1;就没有多出来的这两次析构。这里operator+的实现可以优化,减少不必要的赋值、复制等操作。(函数返回临时变量其实也是一次内存的复制)
更详细一点:调用operator+的时候,因为这个函数是返回一个Renminbi对象,所以系统在栈上的返回值地方分配了一个用于接收返回值的内存空间,然后在这空间之上再压入函数计算过程需要的参数,然后再是函数内部你写的临时变量。然后是计算……,然后返回的时候,你写的临时变量复制到了系统分配的那块返回值空间,然后函数返回,弹栈,你写的临时变量这个时候析构。返回值空间的那个对象赋值给了money2的时候,整个加法过程运算完成,系统分配的那个对象空间释放,析构。
整个过程就是这样的,多的两次析构就这样产生的。
追问
首先感谢您的回答,看了您的回答我知道了哪里错了,但还有个地方不明白,为什么在operator+创建对象时 number没有加1?我把程序中改动:
Renminbi Renminbi::operator +(Renminbi & r)
{
yuan=yuan+r.yuan;
jiao=jiao+r.jiao;
fen=fen+r.fen;
return *this;
}
结果仍然多一次析构,这是不是由于主程序的money2=money+money1产生?
追答
还多出来的那个析构是因为operator +的返回值是Renminbi,而不是Renminbi&。
operator+创建出来的对象不会调用参数的那个构造函数,会调用赋值构造函数,具体你参考下面代码:
class Renminbi
{
private:
int yuan;
int jiao;
int fen;
static int number;
public:
Renminbi(int y,int j,int f):yuan(y),jiao(j),fen(f)
{
cout << "构造函数" << endl;
number++;
}
Renminbi& operator=(const Renminbi& r)
{
cout <<"赋值构造函数"<<endl;
number++;
yuan = r.yuan;
jiao = r.jiao;
fen = r.fen;
return *this;
}

friend ostream& operator<<(ostream& out,const Renminbi & r);
Renminbi operator+(Renminbi & r)const;
Renminbi& operator+=(const Renminbi & r);
~Renminbi()
{cout<<"析构函数"<<"\n";
number--;
cout<<number<<"\n";}
};
百度网友43ebde78e
2011-05-26 · TA获得超过1040个赞
知道小有建树答主
回答量:592
采纳率:0%
帮助的人:698万
展开全部
重载+运算有临时的renminbi对象建立,这个函数结束后就会调用析构,析构掉那个临时对象。
所以,每当你调用这函数就会有那条语句了哦。。。。。
Renminbi Renminbi::operator +(Renminbi & r)const
{
Renminbi m(0,0,0);
m.yuan=yuan+r.yuan;
m.jiao=jiao+r.jiao;
m.fen=fen+r.fen;
return m;
}
本回答被提问者和网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
芝士芯片
2011-05-26 · TA获得超过190个赞
知道小有建树答主
回答量:163
采纳率:0%
帮助的人:167万
展开全部
在调用operator+后,Renminbi对象m作用域结束,故调用析构函数。第二次是调用operator<<时向参数r传递Renminbi对象,调用结束后r作用域结束,故调用析构函数。其余情况类似,也能由于编译器的优化,部分析构不会被调用。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式