以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 C/C++编程思想 』  (http://bbs.xml.org.cn/list.asp?boardid=61)
----  【期待高手】C++类外调用“返回值为对象的函数”产生的“调用copy构造函数”的问题  (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=69255)


--  作者:kaiyuxing
--  发布时间:11/7/2008 8:18:00 PM

--  【期待高手】C++类外调用“返回值为对象的函数”产生的“调用copy构造函数”的问题
在学习copy构造函数时遇到了下述问题(程序在VC++ 6.0下运行):

第一个程序:
#include <iostream.h>
class A{
public:
 A() {}
 A(A& _a){cout<<"Excute Copy Constructor!"<<endl;}
 ~A(){}
};
A f(A& a){return a;}
void main()
{
 A a1,b1;
 b1=f(a1);
}
第一个程序运行结果:
Excute Copy Constructor!

第二个程序:
#include <iostream.h>
class A{
public:
 A() {}
 A(A& _a){cout<<"Excute Copy Constructor!"<<endl;}
 ~A(){}
};
A f(A& a){return a;}
void main()
{
 A a1;
 A b1=f(a1);
}
第二个程序运行结果:
Excute Copy Constructor!

第三个程序:
#include <iostream.h>
class A{
public:
 A() {}
 A(A& _a){cout<<"Excute Copy Constructor!"<<endl;}
};
A f(A& a){return a;}
void main()
{
 A a1;
 A b1=f(a1);
}
第三个程序运行结果:
Excute Copy Constructor!
Excute Copy Constructor!

哪位高手可以解释一下为什么是上述结果?



--  作者:yang_live
--  发布时间:11/12/2008 10:38:00 PM

--  
没看出你的二三个程序有什么区别
--  作者:卷积内核
--  发布时间:11/17/2008 3:07:00 PM

--  
第三个没有析构函数: ~A(){}

--  作者:elfstone
--  发布时间:11/27/2008 1:41:00 PM

--  
以下是引用kaiyuxing在2008-11-7 20:18:00的发言:
在学习copy构造函数时遇到了下述问题(程序在VC++ 6.0下运行):

第一个程序:
#include <iostream.h>
class A{
public:
  A() {}
  A(A& _a){cout<<"Excute Copy Constructor!"<<endl;}
  ~A(){}
};
A f(A& a){return a;}
void main()
{
  A a1,b1;
  b1=f(a1);
}
第一个程序运行结果:
Excute Copy Constructor!

第二个程序:
#include <iostream.h>
class A{
public:
  A() {}
  A(A& _a){cout<<"Excute Copy Constructor!"<<endl;}
  ~A(){}
};
A f(A& a){return a;}
void main()
{
  A a1;
  A b1=f(a1);
}
第二个程序运行结果:
Excute Copy Constructor!

第三个程序:
#include <iostream.h>
class A{
public:
  A() {}
  A(A& _a){cout<<"Excute Copy Constructor!"<<endl;}
};
A f(A& a){return a;}
void main()
{
  A a1;
  A b1=f(a1);
}
第三个程序运行结果:
Excute Copy Constructor!
Excute Copy Constructor!

哪位高手可以解释一下为什么是上述结果?


你是想问程序三中拷贝构造函数为什么会被调用了两次吧

这个实际是编译器的问题,windows平台下vc系列编译器中6.0是存在这个问题的,7.0及以上版本没有这个问题,你可以调整编译选项生成cod文件,对比一下在显式声明析构函数和不声明析构函数的情况下,编译产生的汇编代码的区别就能够明白

6.0编译时在没有显式声明析构函数时,函数f在return时通过调用拷贝构造函数构造的临时对象被带回了主函数过程并再次调用拷贝构造用来构造对象b1,而显式声明了构造函数时,对象b1的地址被作为参数带入了函数f,从而减少了一次拷贝构造,实际这应该是正常的过程,7.0及以上版本编译器编译产生的汇编显示无论是否显式声明析构函数,函数f的执行过程是相同的,也就是按照正常过程实现的

实际上,你的代码中函数f是不合理的,通常此类函数应定义为A& f(A& a),以避免产生临时对象并出现中间拷贝构造


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
31.250ms