一个有趣的对象生灭问题和重载操作符问题,解决有重谢!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

baidu_16788621 2014-12-07 09:36:13
#include<iostream>

using namespace std;

class Ratio{
friend ostream& operator<<(ostream&,const Ratio&);
private:
int num,den;
public:
Ratio(int n=1,int d=1):num(n),den(d){cout<<"Radio lives!"<<endl; };
Ratio(const Ratio& r):num(r.num),den(r.den),id(r.id){cout<<"Copy!"<<endl; };
~Ratio(){cout<<"Radio dies!"<<endl; };
Ratio& operator=(const Ratio&);
Ratio& operator++();
Ratio operator++(int);
};

Ratio& Ratio::operator ++(){
num+=den;
return *this;
}

Ratio Ratio::operator ++(int i){
Ratio temp=*this;
num+=den;
return temp;
}

Ratio& Ratio:: operator=(const Ratio& r){
num=r.num;
den=r.den;
cout<<"Overwrite = !"<<endl;
return *this;
}


ostream& operator<<(ostream& o,const Ratio& r){
o<<r.num<<"/"<<r.den;
return o;
}

void main(){
Ratio one(1,2);

Ratio three=one;
Ratio y=one;
cout<<y++<<endl;
y++=three;
cout<<y<<endl;
}


这一句
cout<<y++<<endl;

的执行结果是:
Copy!
Copy!
Radio dies!
1/2
Radio dies!

①现在第一个问题就来了:前4句我都能知道为什么输出,可是最后一句是怎么回事?同一个对象die了2次吗?
设置了单步运行后发现好像是ostream内部输出来的,可是为什么啊?

②第二个问题是: 这一句
  y++=three;

因为是后++,所以我认为应该先是y=three,再执行y++,结果应为3/2;
可是输出的结果却是y=5/2;
为什么啊?是我代码写得不对吗?

初学c++小白一枚,还望各大神多多指教!
...全文
245 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
勤奋的小游侠 2014-12-08
  • 打赏
  • 举报
回复
产生了一个临时对像,你应该将对像的地址也输出,这样就可以明显地看到那个对像了。只是输出一句提示语句你都不知道是谁调用的。
橡木疙瘩 2014-12-08
  • 打赏
  • 举报
回复

y++=three;
实际上是:

y.operator ++(0).operator=(three);
很明显要先调用operator++(int),然后再调用 operator=(Ratio const &)。three被赋值给y.operator++(int)的返回值,这是一个临时对象,在这条语句结束后,这个临时对象就被释放了。因此这个赋值其实 是个无效操作。
橡木疙瘩 2014-12-08
  • 打赏
  • 举报
回复
问题1:既然两次copy,当然有两次die:

Ratio Ratio::operator ++(int i){
    Ratio temp=*this;//第一次copy:拷贝构造temp
    num+=den;
    return temp;//第二次copy:拷贝构造临时对象
}//第一次die:释放temp;
.....
cout<<y++<<endl;
//第二次die:释放临时对象。
fly_dragon_fly 2014-12-08
  • 打赏
  • 举报
回复
1. ++产生了临时对象,就是里面的temp 2. y++得到的是右值,赋值没有意义, 这语句可以这样看 temp=y , y++, temp=three
赵4老师 2014-12-08
  • 打赏
  • 举报
回复
理解讨论之前请先学会如何观察! 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程! 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步Debug版对应汇编一行! 单步Debug版对应汇编千行不如单步Release版对应汇编一行! 单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。 VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
passion_wu128 2014-12-07
  • 打赏
  • 举报
回复
y++调用的是operator ++(int i),当这个函数返回的时候temp对象析构,所以输出Radio dies! 之后来个main函数的函数栈,cout<<y++<<endl;中y++也是一个临时对象,当执行完这行代码的时候立即析构。所以又输出cout<<y++<<endl; 最后这一句 y++=three;肯定是先执行y++,赋值操作的优先级低于++。所以其实这行最后的效果等同于y=three,当然就是5/2。

64,282

社区成员

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

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