[100分]请 问 这 两 种 用 构 造 函 数 来 初 始 化 对 象 的 方 式 是 否 完 全 等 价

KaKaKaKa 2010-04-15 02:59:18
请问下面两种用构造函数来初始化对象的方式是否完全等价:

1. CFile file(TEXT("log.txt"),CFile::modeCreate | CFile::modeReadWrite);

2. CFile file = CFile(TEXT("log.txt"),CFile::modeCreate | CFile::modeReadWrite);

参数是一模一样的,

《C++ Primer Plus》第五版中说,这两种初始化的方式是等价的。

但我听说有种可能会产生内存泄露,那就是说两种方式不是完全等价的咯?
...全文
202 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
fly_string 2010-04-15
  • 打赏
  • 举报
回复
学习ing................
lvshaoqing 2010-04-15
  • 打赏
  • 举报
回复
CTestRef test5 = CTestRef();
00416E9F lea ecx,[test5]
00416EA2 call CTestRef::CTestRef (41182Fh)

从上面汇编可以看出,只调用了一次。
jbz001 2010-04-15
  • 打赏
  • 举报
回复
我只是来看看
KaKaKaKa 2010-04-15
  • 打赏
  • 举报
回复
taodm,能先告诉下我两者一样么?
taodm 2010-04-15
  • 打赏
  • 举报
回复
去看《exceptional c++》这样的权威书籍。
KaKaKaKa 2010-04-15
  • 打赏
  • 举报
回复
谁懂汇编的,看看一样不?
ora-0600 2010-04-15
  • 打赏
  • 举报
回复
学习中ing...
symphia 2010-04-15
  • 打赏
  • 举报
回复
这应该是属于 返回值优化 的情况吧
KaKaKaKa 2010-04-15
  • 打赏
  • 举报
回复

CFile file=CFile(TEXT("a.txt"),CFile::modeCreate| CFile::modeWrite);
TCHAR * content=TEXT("xxx");
file.Write(content,sizeof(TCHAR)*lstrlen(content));
file.Close();


上面这段简单的代码在winxp上运行没什么问题

但在WinCE平台上运行,就出错了,弹出的Error信息居然是乱码

然后我将第一句换成:
CFile file(TEXT("a.txt"),CFile::modeCreate| CFile::modeWrite);

就没问题了。

所以我才有此贴,怀疑两者实不一样。

不信的朋友可以在WinCE上在证实下,WinCE里的CFile跟winxp平台的构造都是一样的。
zhangweiit 2010-04-15
  • 打赏
  • 举报
回复
2. CFile file = CFile(TEXT("log.txt"),CFile::modeCreate | CFile::modeReadWrite);

我开始也想当然的以为,会调用一次复制构造函数
但是再认真一想,其实,不是这样的,因为,变量定义的语句,是从右执行到左,右边完成构造后,直接赋值给左边的,于是,左边的不再进行构造

经过实验,也确实是这样
zhangweiit 2010-04-15
  • 打赏
  • 举报
回复
不好意思,我再认真分析了一下,我上面说的有误,
其实,两种都是调用1次构造函数
LittleJohny 2010-04-15
  • 打赏
  • 举报
回复
#include "stdafx.h"
#include<iostream>
using namespace std;

class Person
{
public:
Person(int age, float height):m_age(age),m_height(height)
{
cout<<"constructor invoked"<<endl;
}
Person( const Person & m)
{
m_age= m.m_age;
m_height=m.m_height;
cout<<"copy constructor invoked"<<endl;
}

private:
int m_age;
float m_height;

};


int main()
{
//Person peter(12,3.56);
//Person steven = peter;

Person steven = Person(13,1.45);
system("pause");
}


应该是等价的。从运行结果来看,拷贝构造函数根本没有被调用的。
zhangweiit 2010-04-15
  • 打赏
  • 举报
回复
1. CFile file(TEXT("log.txt"),CFile::modeCreate | CFile::modeReadWrite);
只是普通的调用构造函数1次

2. CFile file = CFile(TEXT("log.txt"),CFile::modeCreate | CFile::modeReadWrite);
调用构造函数两次
第一次,发生在CFile(TEXT("log.txt"),CFile::modeCreate | CFile::modeReadWrite);
此时,会产生一个CFile类型的临时变量,设它为__tempFile
然后,__tempFile会复制给file,这时,又调用了CFile类的“复制构造函数”

附,第三种
CFile file = new CFile(TEXT("log.txt"),CFile::modeCreate | CFile::modeReadWrite);
此时,调用构造函数一次,并在堆中开辟了一块内存,记得delete

总结:
第一种,最常用的方式,不产生堆内存,管理不复杂
第二种,一般不使用
理论上来说,第二种也不会产生内存泄漏的,临时变量只是一个local变量,作用域结束后会自动回收的
第三种,file需要在一个过程中,指向不同CFILE变量的时候,当然用指针了

bluehousedahui 2010-04-15
  • 打赏
  • 举报
回复
学习中……
KaKaKaKa 2010-04-15
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 keiy 的回复:]
貌似一样:
class T;
T t=T(...); //就是构造
测试程序:
class T
{
public:
T() { ::MessageBox(NULL,"T","MESS",0 );}
T(char *) {::MessageBox(NULL,"T(char *)","MESS",0 );}
} ;
...
T t1("aaa");//调用T(char……
[/Quote]

大哥,你的徽章好多啊。
这个我也听很多人说两种方式不是完全一样的。
后者实际上是创建了两个对象了

希望有高人释疑
sports98 2010-04-15
  • 打赏
  • 举报
回复
支持标题
柯本 2010-04-15
  • 打赏
  • 举报
回复
貌似一样:
class T;
T t=T(...); //就是构造
测试程序:
class T
{
public:
T() { ::MessageBox(NULL,"T","MESS",0 );}
T(char *) {::MessageBox(NULL,"T(char *)","MESS",0 );}
} ;
...
T t1("aaa");//调用T(char *)构造
T t2=T("aaaa"); //同样调用T(char *)构造
CCCCCCCCCCCCCCC 2010-04-15
  • 打赏
  • 举报
回复
赞标题
KaKaKaKa 2010-04-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 lhcwjy 的回复:]
第一个是创建了一个对象,第二个是先创建了一个对象,然后又复制了一个对象
[/Quote]
这个解释貌似是正确的。
那就是说这两种写法不是完全等价的。
《C++ Primer Plus》有误!
KaKaKaKa 2010-04-15
  • 打赏
  • 举报
回复
CFile file = CFile(TEXT("log.txt"),CFile::modeCreate | CFile::modeReadWrite);

据说这种方式是等号后面的已经创建了一个CFile的对象,然后等号是复制一份给file。
不知道对不对?
加载更多回复(4)

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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