一道有趣的题目
2005-09-05 22:01
375 查看
今天在群里有人问了一个有趣的问题。
#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这一步就出错了,还没到堆栈呀。
那么到底是什么原因呢?
#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这一步就出错了,还没到堆栈呀。
那么到底是什么原因呢?
相关文章推荐
- 一道有趣的题目,看看你的观点是分别开出拿些人?
- 一道有趣的题目
- 一道有趣的C#考试题目
- 【预习笔记】一道很有趣的有关java类加载初始化的题目
- 关于byte的一道有趣的题目
- 一道有趣的++运算题目
- 一道有趣的题目
- 一道有趣的题目
- 一道有趣的笔试题目!
- 一道有趣的C#考试题目
- 一道有趣的C#考试题目
- 在CSDN上看到的一道有趣的网易笔试题目--附答案
- 一道有趣的题目007
- 一道有趣的题目
- 一道有趣的循环题目
- 前几天遇到一道有趣的题目 一座楼有10层,兔子可以跳跃的层数可以为1,2或者3,那么兔子到达10层有多少种跳法并列出各种情况。
- 一道有趣的SQL题目
- 杭电OJ——1025 Constructing Roads In JGShining's Kingdom(比较有趣的一道题目,思路详解)
- 自家人不认识自家人——考你一道有趣的Javascript小题目
- 一道有趣的题目 转F