为什么要有异常------why?
1.通过返回值表达错误.
malloc, fcntl
局部对象都能得到正确析构;
层层判断返回值,流程繁琐;
2.setjmp, longjmp,远程跳转
例如:
jump_buf g_env;
if(setjmp(g_env) == -1)
{
错误处理代码;
}
longjmp(g_env, -1);
一步到位进行错误处理,流程简单;
局部对象会失去被析构的机会;
3.异常处理
局部对象都能得到正确析构;
一步到位进行错误处理,流程简单;
-------------------------------------------------------------------------------------------------------------
异常的语法--what
1.异常的抛出
throw 异常对象;
异常对象可以是基本类型的变量,也可以是类类型的对象;
当程序执行错误分支时抛出异常;
2.异常的捕获与处理
try
{
可能抛出异常的语句块;
}
catch(异常类型1 异常对象1)
{
处理异常类型1的语句
}
catch(异常类型2 异常对象2)
{
处理异常类型2的语句
}
.
.
.
catch(...)
{
处理其他类型异常的语句块;
}
----------------------------------------------------------------------------------------------------------------
3.异常的执行流程
异常处理的流程,始终沿着函数调用的逆序,依次执行右花括号,直到try的右花括号;
保证所有的局部对象都能被正确的析构,然后会根据异常对象的类型,匹配相应的catch分支,
进行有针对性的处理;如果没有对应匹配分支,操作系统会捕获并杀死进程;
----------------------------------------------------------------------------------------------------------------
异常处理的使用方法------how
1.抛出基本类型的异常,用不同的值代表不同的错误;
2.抛出类类型的异常,用不同的类型表示不同的错误;(推荐)
注意:不能抛出局部对象的地址;
最简单方法:抛出一个匿名对象,catch对象的引用;
catch 是最先匹配原则(函数重载是最优匹配原则)
3.通过类类型的异常携带更多的诊断信息;
4.忽略异常和继续抛出异常(throw;);
5.异常说明(给函数的调用者看)
在一个函数的形参表后面写如下语句:
.......形参表)throw (异常类型1,异常类型2,异常类型3,.......)
{.......}
表示这个函数可以被捕获的异常;
形参表)throw()-----表示这个函数所抛出的任何异常都不能被捕获;
没有异常说明--------默认这个函数所抛出的任何异常都可以被捕获;
6.使用标准异常
#include <stdexcept>
----------------------------------------------------------------------------------------------------------------
构造函数中的异常
构造函数可以抛出异常,而且有些适合还必须抛出异常,以通知调用者构造过程中发生的错误;
如果在一个对象的构造过程中抛出了异常,那么这个对象就被称为不完整对象;
不完整对象的析构函数永远不会被执行,因此需要在
throw之前手动释放动态分配的内存;
----------------------------------------------------------------------------------------------------------------
析构函数中的异常
1.
永远不要在析构函数中抛出异常(可能出现未定义的后果);
2.通过try-catch拦截所有可能引发的异常;
1.C++中的I/O流库(输入输出流是对程序来说的)
C: fopen/fclose, fread/fwrite, fprintf/fscanf, fseek/ftell...
C++: 对C基本的I/O操作做了类的封装,其功能没有任何差别,用法和C的I/O流也非常近似;
sscanf
----------------------------------------------------------------------------------------------------------------
2.格式化I/O(看成各种数据类型的数据序列)
<</>>
hexdump -C xxx.txt 可以查看文件的ASCII码(16进制表示);
----------------------------------------------------------------------------------------------------------------
3.非格式化I/O(看成字符串)
put/get
----------------------------------------------------------------------------------------------------------------
4.随机I/O
seekp/seekg
tellp/tellg
----------------------------------------------------------------------------------------------------------------
5.二进制I/O
read/write
k: 0-255
A^k = B 加密
B^K = A 解密
----------------------------------------------------------------------------------------------------------------
6.格式控制(略)
----------------------------------------------------------------------------------------------------------------
7.字符串流(略)