简单一段代码,2行看不懂,求高手指点!

yiruirui0507 2010-11-08 10:58:12
#include<iostream>
using namespace std;
class A
{
public:
A(int x){i=x;cout<<"构造函数执行!"<<i<<endl;}
~A(){cout<<"析构函数执行!"<<i<<endl;}
void get(){cout<<i<<endl;}
A(A&){cout<<"拷贝构造函数执行!"<<endl;}
A&operator=(const A& ob);
private:
int i;
};
A& A::operator=(const A& ob)
{
cout<<"赋值操纵!"<<endl;
this->i=ob.i;
return *this;
}
int main()
{
A a(99);
a.get();
a=1000;
A b=A(300);
A c=a;
return 0;

}

以上代码有一些不懂之处,首先
a=1000;如何理解?我的理解:这里是一个强制类型转换,让int->A,首先使用构造函数来创建一个临时对象,然后初始化该临时对象的成员i为1000,然后再赋值给左边的对象a.应该没有什么问题吧!
接下来
A b=A(300);这句的理解:创建一个临时对象,初始化成员为300,然后这里我就不明白了,这里我认为应该调用拷贝构造函数来初始化b啊 ,最后

A c=a,同样应该调用拷贝构造函数来初始化c啊, 但是结果并非如此,所以特地来此求助.望高手说明证据的来源,比如什么书籍?c对象前面没有申明过,所以这里应该用拷贝构造函数,不知道什么原因导致的没用?
...全文
307 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
yiruirui0507 2010-11-08
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 yiruirui0507 的回复:]
引用 22 楼 gules 的回复:
你自己在拷贝构造函数中只输出,不进行实际的复制,那么 A c = a;时,对象c的值就是不确定的!

另外,构造与析构的次数没有问题啊,三个对象a b c + 一个临时对象 A(1000)。


首先,对象c的值就是不确定的!
你这句话就是错误的,调用拷贝构造函数来实力化c,c的值已经确定跟a相等.

另外,析构跟构造的次数也有问题啊,一个4……


[/Quote]
抱歉,是4次,数错了!我的错!
gules 2010-11-08
  • 打赏
  • 举报
回复
有没有搞错啊,你在拷贝构造函数中只有一句:
cout<<"拷贝构造函数执行!"<<endl;
c对象何来拷贝?改为:

A(const A& rhs){cout<<"拷贝构造函数执行!"<<endl; i = rhs.i; }

试试看,是不是等于1000了?

构造和析构的次数,根据你的输出:

构造函数执行!99 // 构造1次
99
构造函数执行!1000 // 构造2次
赋值操纵!
析构函数执行!1000 // 析构1次
构造函数执行!300 // 构造3次
拷贝构造函数执行!1000 // (拷贝)构造4次
析构函数执行! -858993460 // 析构2次
析构函数执行!300 // 析构3次
析构函数执行!1000 // 析构4次

何来析构5次?!

你自己再想想吧。
yiruirui0507 2010-11-08
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 gules 的回复:]
你自己在拷贝构造函数中只输出,不进行实际的复制,那么 A c = a;时,对象c的值就是不确定的!

另外,构造与析构的次数没有问题啊,三个对象a b c + 一个临时对象 A(1000)。
[/Quote]

首先,对象c的值就是不确定的!
你这句话就是错误的,调用拷贝构造函数来实力化c,c的值已经确定跟a相等.

另外,析构跟构造的次数也有问题啊,一个4次一个5次,明显不合理吗?
你在想想吧!仍然感谢你的回复!
赵4老师 2010-11-08
  • 打赏
  • 举报
回复
做个可能不太恰当的比喻:
人想让狗帮忙逮只兔子,可是人说话狗听不懂,于是人发明了一种介乎人言和狗语之间的语言,即口令。
人想让电脑帮忙做计算,可是人话电脑听不懂,于是人发明了一种介乎人言和汇编机器码之间的语言,即C语言。
人对狗的口令得让人容易学、也得让狗容易懂。
C语言同样得让人容易学、也得让电脑容易懂。
相比之下C++、Java就是人学得费劲、电脑也经常闹不懂。

单步调试和设断点调试是程序员必须掌握的技能之一。
gules 2010-11-08
  • 打赏
  • 举报
回复
你自己在拷贝构造函数中只输出,不进行实际的复制,那么 A c = a;时,对象c的值就是不确定的!

另外,构造与析构的次数没有问题啊,三个对象a b c + 一个临时对象 A(1000)。
yiruirui0507 2010-11-08
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 gules 的回复:]
A b=A(300); // 确实不需要调用拷贝构造,编译器直接在对象b上构造对象,也就是相当于 A b(300); 编译器还是蛮聪明的嘛!

但 A c = a; 确实调用了拷贝构造函数。
[/Quote]

输出结果你没发现什么吗?
构造了4次,析构了5次,你就不觉得奇怪吗?
析构函数执行! -858993460
这个析构的是哪个对象?
gules 2010-11-08
  • 打赏
  • 举报
回复
A b=A(300); // 确实不需要调用拷贝构造,编译器直接在对象b上构造对象,也就是相当于 A b(300); 编译器还是蛮聪明的嘛!

但 A c = a; 确实调用了拷贝构造函数。
yiruirui0507 2010-11-08
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 gules 的回复:]
VC6.0就搞不清楚了,反正我不用。
临时对象是不能绑定于非常量引用的,我在gcc上如果不加const编译通不过!
[/Quote]

gcc上的结果是什么?
gules 2010-11-08
  • 打赏
  • 举报
回复
VC6.0就搞不清楚了,反正我不用。
临时对象是不能绑定于非常量引用的,我在gcc上如果不加const编译通不过!
yiruirui0507 2010-11-08
  • 打赏
  • 举报
回复
问题依然没有解决,期待解决办法.............
yiruirui0507 2010-11-08
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 gules 的回复:]
看了你的输出结果,知道了你的错误原因在于拷贝构造函数定义错误,应该写为:

A(const A&) { cout<<"拷贝构造函数执行!"<<endl; }

试试吧,应该不会有问题了!
[/Quote]

const 加上也还是一样啊,没任何变化,VC6.0!
游牧小小诗人 2010-11-08
  • 打赏
  • 举报
回复
a = 1000;
是赋值操作吧,,操作符重载
A&operator=(const A& ob);

1000 先创建 临时A对象
然后再复制构造函数
gules 2010-11-08
  • 打赏
  • 举报
回复
看了你的输出结果,知道了你的错误原因在于拷贝构造函数定义错误,应该写为:

A(const A&) { cout<<"拷贝构造函数执行!"<<endl; }

试试吧,应该不会有问题了!
yiruirui0507 2010-11-08
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hqin6 的回复:]
a=1000;如何理解?我的理解:这里是一个强制类型转换,让int->A,首先使用构造函数来创建一个临时对象,然后初始化该临时对象的成员i为1000,然后再赋值给左边的对象a.应该没有什么问题吧!

我的理解:1000作为参数调用A(int)构造函数!如果想要避免这种隐式转换,可以在A(int)前使用explicit声明!这里不涉及到临时对象的说法。

接下来
A b=A(300);这……
[/Quote]
根据结果, 第2句确实调用了拷贝构造函数啊,你说没有???
通天 2010-11-08
  • 打赏
  • 举报
回复
用的这个
A& A::operator=(const A& ob)
{
cout<<"赋值操纵!"<<endl;
this->i=ob.i;
return *this;
}
yiruirui0507 2010-11-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 ouyh12345 的回复:]
a=1000;
不是强制类型转换,有拷贝构造函数
[/Quote]

错了,结果中没有出现拷贝构造函数!
太乙 2010-11-08
  • 打赏
  • 举报
回复
我说的是A a=1000;这种方式。。。
yiruirui0507 2010-11-08
  • 打赏
  • 举报
回复
vc 6下运行结果:
构造函数执行!99
99
构造函数执行!1000
赋值操纵!
析构函数执行!1000
构造函数执行!300
拷贝构造函数执行!1000
析构函数执行! -858993460
析构函数执行!300
析构函数执行!1000
太乙 2010-11-08
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 hqin6 的回复:]

a=1000;如何理解?我的理解:这里是一个强制类型转换,让int->A,首先使用构造函数来创建一个临时对象,然后初始化该临时对象的成员i为1000,然后再赋值给左边的对象a.应该没有什么问题吧!

我的理解:1000作为参数调用A(int)构造函数!如果想要避免这种隐式转换,可以在A(int)前使用explicit声明!这里不涉及到临时对象的说法。

接下来
A b=A(300);……
[/Quote]无视。。。。看错了。。。
gules 2010-11-08
  • 打赏
  • 举报
回复
那么你的结果是什么呢,打印出来看看?
加载更多回复(7)

64,654

社区成员

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

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