关于析构函数的一个问题

xiaoxixing 2007-05-31 11:15:02
此程序最后居然输出三次"析构"字符串?
真是费解,拜托大家!
#include<iostream>
using namespace std;
class point
{
public:
point(int xx,int yy){x=xx,y=yy;}
point(point &p);
~point(){cout<<"析构"<<endl;}
private:
int x;
int y;
};
point::point(point &p)
{
x=p.x;
y=p.y;
}
point fun2()
{
point A(1,2);
return A;
}
int main()
{
point B(4,5);
B=fun2();
return 0;
}
...全文
1939 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
jyk0822 2007-06-04
  • 打赏
  • 举报
回复
大家可以将析构函数改一下,看到底析构在哪里,可以改成这样
~point()
{
cout<<x<<' '<<y<<endl;
cout<<"析构"<<endl;
}
最后出现的结果是:1 2
析构
1 2
析构
1 2
析构
我用的软件是VC++6.0
hertz2007 2007-06-03
  • 打赏
  • 举报
回复
#include<iostream>
using namespace std;
class point
{
public:
point(int xx,int yy){x=xx,y=yy;cout<<"point构造函数"<<endl;}
point(point &p);
~point(){cout<<"析构"<<endl;}
private:
int x;
int y;
};

point::point(point &p)
{
x=p.x;
y=p.y;
cout<<"point拷贝构造函数"<<endl;
}

point fun2()
{
point A(1,2);//调用A的构造函数
cout<<"fun2()内部"<<endl;
return A;//返回对象A之前,构造临时对象并调用拷贝构造函数;函数结束时调用临时对象和A的析构函数;
}

int main()
{
point B(4,5);//调用B的构造函数
B=fun2();//拷贝构造,对B赋值,之后调用临时对象的析构函数
return 0;//函数结束,调用B的析构函数
}
BenKwan 2007-06-03
  • 打赏
  • 举报
回复
怎么我用g++编译你这代码编译不过!!
提错如下:
---------- Compile(g++) ----------
Noname1.cpp: In function `point fun2()':
Noname1.cpp:29: error: no matching function for call to `point::point(point)'
Noname1.cpp:16: note: candidates are: point::point(point&)

输出完成 (耗时: 0 秒) - 正常终止
但是在我朋友的电脑上编译就通过了~不过他的g++上面只析构了2次!
就是他的gcc版本是旧一点的~3.2.*的~我的是3.4.*的~~
什么原因?
但是在拷贝构造函数的参数前加上const就可以编译通过~~
谁来解释一下?
surgent 2007-06-03
  • 打赏
  • 举报
回复
point B(4,5); 构造一次
point A(1,2); 构造一次
B=fun2(); /拷贝构造一次,然后析构
zengkun100 2007-06-03
  • 打赏
  • 举报
回复
point A(1,2);
return A;

最好的写法当然是:return point(1,2);这样没有经过优化的编译器也不会产生临时对象。
Stefine 2007-06-03
  • 打赏
  • 举报
回复
B=fun2();//拷贝构造,对B赋值,之后调用临时对象的析构函数

赋值吧?

point B=fun2();//这才是COPY
rainv 2007-06-02
  • 打赏
  • 举报
回复
mark
pass86 2007-06-02
  • 打赏
  • 举报
回复
临时对象
mfkdyq 2007-06-02
  • 打赏
  • 举报
回复
此程序根本不能通过编译。
kevinlynx 2007-06-02
  • 打赏
  • 举报
回复
3次是常规,2次是优化好的。

point func()
{
point point_obj;

return point_obj;
}

貌似在cfront里C++老豆是这样做的:(参看<Inside the C++ object model> )
void func( point &ret )
{
ret = point_obj;

return ;
}

对于:
B = func();

会被优化为:
func( B ); //c++伪码,func被伪码成 func( point &ret )

-----
有些东西懂多了反而被搞混~
superhero122 2007-06-01
  • 打赏
  • 举报
回复
各位楼主,注意了,我用VC2005调试,只输出两次‘析构’ 啊!!怎么回事呢,和各位楼主解释的好象有出入哦?????????
----------------------------------------------------------------

这和vc2005本身有关系,可能是由于它的对于内存的管理更好一些
liuxing142 2007-06-01
  • 打赏
  • 举报
回复
真的佩服各位的见解...说真的,我也不知道这些...惭愧...
ljx_cug 2007-06-01
  • 打赏
  • 举报
回复
稍微改一下,也是只输出3次析构,不能理解?
int main()
{
point B(4,5);
point C = fun2();
return 0;
}
lauxp 2007-06-01
  • 打赏
  • 举报
回复
NRV optimization

point fun2()
{
point A(1,2);
return A;
}

void fun2(point& p)
{
p::Point();
// 这里可以被省略,因为
// point B(4,5); 已经完成构造
// B = fun2(); ;
return ;
}

所以两次应该是比较好的编译器
taodm 2007-06-01
  • 打赏
  • 举报
回复
因为有些东西叫“优化”
Braint_Yuan 2007-06-01
  • 打赏
  • 举报
回复
各位楼主,注意了,我用VC2005调试,只输出两次‘析构’ 啊!!怎么回事呢,和各位楼主解释的好象有出入哦?????????
ljx_cug 2007-06-01
  • 打赏
  • 举报
回复
不能返回一个临时对象的引用
之所以调用3次析构,主要是return A; 进行了一次临时对象的拷贝
miarchen 2007-06-01
  • 打赏
  • 举报
回复
首先,在你调用fun2()函数时,它会生成一个用来装入返回对象的隐藏对象,在函数内部又有一个对象A,当它的作用域结束后,调用析构函数(第一次),当在主函数中对fun2()的函数返回对像进行赋值给对象B后,隐藏对象需调用析构函数(第二次),最后程序结束前调用B的析构函数(第三次).
还有函数返回的对象是进行赋值给对象B,而不是拷贝,因为B已进行初始化了.
拷贝函数和赋值函数最大的区别就是它用于对象初始化.
以上是我个人想法,因刚学C++才一个星期,希望大家指教.
shaohua1986 2007-06-01
  • 打赏
  • 举报
回复
楼上说的都很对
不过你用引用看看
point & fun2()
{
point A(1,2); //2处: 定义了一个A,
return A; //这里返回A的引用
}
这样就不会创建临时对象,所以就不会调用三次西够函数了.
记得给我加分啊
yc_8301 2007-06-01
  • 打赏
  • 举报
回复
抱歉写错了。。。555

把return A;该成
return point(1,2);
加载更多回复(14)

64,685

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧