面试的一个奇怪的问题
#include <iostream.h>
class A
{
public:
A()
{
cout<<"This is A Construction"<<endl;
}
virtual~A()
{
cout<<"This is A destruction"<<endl;
}
};
A fun()
{
A a;
return a;
}
void main()
{
{
A a;
a=fun();
}
}
结果为什么是:
This is A Construction
This is A Construction
This is A destruction
This is A destruction
This is A destruction
不是说构造和析构是成对的吗?
为什么少了一个构造呢?
问题点数:20、回复次数:30Top
1 楼LoveYouJustOneDay(哈哈)回复于 2005-07-26 21:12:24 得分 1
C:\Documents and Settings\xhy>"C:\Documents and Settings\xhy\??\Project1.exe"
This is A Construction
This is A Construction
This is A destruction
This is A destruction
C:\Documents and Settings\xhy>
这个是我用 g++ 编译之后执行的结果Top
2 楼llf_hust()回复于 2005-07-26 21:22:40 得分 1
#include <iostream.h>
class A
{
public:
A()
{
cout<<"This is A Construction"<<endl;
}
virtual~A()
{
cout<<"This is A destruction"<<endl;
}
A(const A &a)
{
cout<<"a"<<endl;
}
};
A fun()
{
A a;
return a;
}
void main()
{
A a;
a=fun();
}
//This is A Construction
//This is A Construction
//a
//This is A destruction
//This is A destruction
//This is A destruction
写成这样就很容易理解了,在return a的时候产生好一个临时对象要调用构造函数。所以要构造三次,当然要析构三次Top
3 楼somexing(somexing)回复于 2005-07-26 21:24:52 得分 1
vc++ 6 中
This is A Construction
This is A Construction
This is A destruction
This is A destruction
This is A destructionTop
4 楼zsx123(爱生活,爱A片)回复于 2005-07-26 21:29:45 得分 0
写成这样就很容易理解了,在return a的时候产生好一个临时对象要调用构造函数。所以要构造三次,当然要析构三次
---------------------------------
为什么只打印了两次构造函数?却析构三次.
不是要构造一次就要析构吗?Top
5 楼yhbttfile(小兵)回复于 2005-07-26 21:43:33 得分 1
// Demo.cpp : 定义控制台应用程序的入口点。
//
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout<<"This is A Construction"<<endl;
}
virtual~A()
{
cout<<"This is A destruction"<<endl;
}
A(const A &oth)
{
cout<<"This is A copy Construction"<<endl;
}
};
A fun()
{
A a;
return a;
}
void main()
{
A a;
a=fun();
}
这个问题以前有人问过。fun函数返回的临时对象是通过拷贝构造函数产生的。
——————————————————————————
This is A Construction
This is A Construction
This is A copy Construction
This is A destruction
This is A destruction
This is A destructionTop
6 楼JohnTitor(贱畜)回复于 2005-07-26 21:45:13 得分 1
楼上正解Top
7 楼somexing(somexing)回复于 2005-07-26 21:48:36 得分 1
似乎因为拷贝构造函数的对象不是调用construction, 只调用copy Construction,所以少了一个construction function ....Top
8 楼netfairy(泡泡猪)回复于 2005-07-26 22:44:43 得分 1
怀疑有的编译器会把那个临时变量优化掉Top
9 楼Gdlian(古德里安)回复于 2005-07-26 23:29:00 得分 1
建议楼主看effective c++Top
10 楼K()回复于 2005-07-27 00:21:25 得分 1
copyTop
11 楼yesiloveyou(下意识的弯了一下腰,TMD,踩狗屎了)回复于 2005-07-27 01:19:37 得分 1
upTop
12 楼jiajun2001(Jagen(嘉俊))回复于 2005-07-27 09:38:41 得分 1
yhbttfile(小兵) 正确!Top
13 楼xuanwenchao(xuanwenchao)回复于 2005-07-27 10:12:52 得分 1
yhbttfile(小兵) 的解释非常正确!Top
14 楼wjn99wjn(九九)回复于 2005-07-27 10:41:35 得分 1
那为什么
二楼 LoveYouJustOneDay(哈哈) 用g++的编译结果不是如此呐?
编译器的问题?
Top
15 楼redspider9999(亢龙有悔)回复于 2005-07-27 11:06:55 得分 1
对的
return a时调用了类默认的拷贝构造函数
你可以自己写个拷贝构造函数,让它也打印“This is A Construction”,这样就会看到3个构造和3个析构是匹配的了Top
16 楼sunlu_eric(天使预备役)回复于 2005-07-27 11:28:01 得分 1
哦,默认拷贝构造函数,多出的那一个是返回值的吧!Top
17 楼xiao_xiao_zi(笑小子)回复于 2005-07-27 11:58:26 得分 1
有依次是默认拷贝构造函数
而你没有重写,当然不会显示了
void main()
{
A a;
一次
A fun()
{
A a;
第二次
return a的时候产生一个临时对象保存fun函数的返回值
第三次Top
18 楼zhoufanking(风铃)回复于 2005-07-27 12:07:12 得分 1
upTop
19 楼WoodJohn(天在下雨,云在哭泣)回复于 2005-07-27 12:11:19 得分 1
学习Top
20 楼DiabloWalkOnTheEarth(我想到个绝妙的昵称,只是地方太小,写不下)回复于 2005-07-27 12:34:52 得分 1
有个调用鸟 copy ctor. 编译器对返回对象一般会进行优化(NRV) , 八过 cl 和 gcc 优化地策略好像不同, 标准好像也木对这种优化实施的条件做具体规定.Top
21 楼wsnly13(王五)回复于 2005-07-27 12:47:09 得分 1
在类中添加一个拷贝构造函数 就能看到在输出结果。
A(const A& t)
{
cout<<"copy constuction"<<endl;
}
This is A Construction
This is A Construction
copy constuction-----------------》》》》》fun()返回时调用。
This is A destruction
This is A destruction
This is A destruction
Top
22 楼rain_hui(当我开始偷偷的想你)回复于 2005-07-27 15:09:22 得分 0
当函数中的局部对象被被返回给函数调者时,也将建立此局部对象的一个临时拷贝,拷贝构造函数也将被调用 ,例如:
CTest func()
{
CTest theTest;
return theTest
}
所以相当于进行了三次构造函数的调用
Top
23 楼wzjall(风)回复于 2005-07-27 15:34:56 得分 0
thinking in c++ 一书中有类是的示例,解释是这样的:因为没有自己的拷贝构造函数,建立此局部对象的一个临时拷贝时,默认的拷贝构造函数将被调用 ,而默认的拷贝构造函数调用是按位拷贝的。Top
24 楼wrui()回复于 2005-07-27 23:47:36 得分 0
fun(){}返回时产生一个临时对象,a = fun();将调用默认拷贝构造函数,但是默认构造函数没有写输出语句。而析构函数没有重载,所有对象的析构都是调用同一个函数,故为显示创建对象语句2次,而显示析构对象语句3次的原因!Top
25 楼xjp6688(大平/要做必须最好)回复于 2005-07-28 08:12:35 得分 0
bcb6下面
#include <cstdlib>
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout<<"This is A Construction"<<endl;
}
~A()
{
cout<<"This is A destruction"<<endl;
}
A(const A &rhs)
{
cout<<"this is copy constructor"<<endl;
}
A& operator=(const A &rhs)
{
cout<<"this is assignment operator"<<endl;
}
};
A fun()
{
A a;
return a;
}
int main()
{
{
A a;
a=fun();
}
system("pause");
return 0;
}
------------------
结果
--------------------
This is A Construction
This is A Construction
this is copy constructor
This is A destruction
this is assignment operator
This is A destruction
This is A destruction
Top
26 楼xjp6688(大平/要做必须最好)回复于 2005-07-28 08:13:42 得分 0
GCC下
#include <cstdlib>
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout<<"This is A Construction"<<endl;
}
~A()
{
cout<<"This is A destruction"<<endl;
}
A(const A &rhs)
{
cout<<"this is copy constructor"<<endl;
}
A& operator=(const A &rhs)
{
cout<<"this is assignment operator"<<endl;
}
};
A fun()
{
A a;
return a;
}
int main()
{
{
A a;
a=fun();
}
system("pause");
return 0;
}
--------------------------------
结果
------------------------------
This is A Construction
This is A Construction
this is assignment operator
This is A destruction
This is A destruction
Top
27 楼xjp6688(大平/要做必须最好)回复于 2005-07-28 08:14:04 得分 0
想必GCC做了优化!
Top
28 楼zhaozhencn(FlyingDonkey)回复于 2005-07-28 08:33:40 得分 0
在没有进行优化的情况下,执行过程如下:
#include <iostream.h>
class A
{
public:
A()
{
cout<<"This is A Construction"<<endl;
}
virtual~A()
{
cout<<"This is A destruction"<<endl;
}
};
A fun()
{
A a; //2 构造对象.
return a; //3 调用copy construct function 构造临时对象,之后,析构a
}
void main()
{
{
A a; //1 第一次构造函数.
a=fun(); //4 调用assignment function 将临时对象赋值给a. 执行完这句后,临时对象寿终正寝, 即调用其析构函数.
} //5 析构 a
}
Top
29 楼ningzhiyu(凝滞雨)回复于 2005-07-28 08:36:49 得分 0
学习,学习……Top
30 楼login__whf(还买烟不*_*)回复于 2005-07-28 08:44:40 得分 0
upTop




