一道有趣的题目

今天在群里有人问了一个有趣的问题。

#include <conio.h>
#include <iostream>
using namespace std;

// 只要有e诞生或死亡,就输出个东西来
class e
{
public:
e(void){ cout<<"default constructor"<<endl;}
e(const e& e1){ cout<<"copy constructor"<<endl;}
e& operator=(const e& e1){ cout<<"assignment"<<endl;}
~e(void){ out<<"destructor"<<endl;}
};

// 扔出一个异常
void fun(void){       throw(0);}

// 调用一个会扔出异常的函数
void fun_e1(e e1){ fun();}

// 通过溢出产生一个异常出来
void fun_e2(e e2){ int i; i /= (i = 0);}

// 手工抛出一个异常
void fun_e3(e e3){  throw(0);}

int _tmain(int argc, _TCHAR* argv[])
{
 e e1;

 try
 {
  fun_e1(e1);
 }
 catch(...)
 {
 }

 return 0;
}

class view
{
public:
view(void)
{ cout<<"-oh my god"<<endl;}

~view(void)
{
     cout<<"-can u see"<<endl;
     while(!kbhit());
}
}v;


// 一个Object如果被完美创建,那么在离开它的scope时,会被destructor
// 在try中,调用fun_e1, 得到输出
-oh my god
default constructor
copy constructor
destructor
destructor
-can u see

// 在try中,调用fun_e2,得到输出
-oh my god
default constructor
copy constructor
destructor
-can u see

// 在try中,调用fun_e3,得到输出
-oh my god
default constructor
copy constructor
destructor
destructor
-can u see

// 注意调用fun_e2,即不是显式throw一个异常的时候
// 我们得到(至少是在输出上)两个构造和一个析构,这少
// 掉的一个析构跑到哪里去了?

两次调用差别在于一次是Throw,一次是除零溢出。为什么除零溢出导致少了一次析构呢?昨天刚刚看了
异常处理,所以分析是因为对象是临时变量,i也是临时变量,i溢出导致复写了e,似乎很有道理,但是认真
想了一下,不对,i /= (i = 0); 应该是
xor eax,eax
idiv eax,eax
mov [esp-4],eax
应该在 idiv eax,eax这一步就出错了,还没到堆栈呀。

那么到底是什么原因呢?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值