一.知识点
异常捕捉机制:
一旦执行throw立刻转到catch,不再进行throw下面内容;
可设置不同类型throw值,但一次只能throw一个值, 与return类似
若一个类型有多个值,需拷贝,可动态内存分配后指针传递, 但麻烦. 通常直接const char* err接收即可
...throw "肉肉好帅!";
...throw "肉肉好傻!";
...throw "肉肉好萌!";
try(){
...
}
catch(const char* err){
cout<< err <<endl;
}
catch顺次进行,只执行一个匹配分支;catch(…)通配。
如果throw float无匹配,会中断(缺省功能会调用abort终止程序),并显示Microsoft C++异常:内存位置xxxxxx处的float
最近的catch才能拿到throw,若最近的catch再throw,才会throw给次近的catch
若throw;
上次接到啥就扔啥.要是没接到就出错!
一般只throw异常!
二.示例
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <vld.h>
using namespace std;
#define BUFFER_SIZE 1024//字节数
#define ELEMENT_SIZE 1
class Beauty {
public:
Beauty() {}
~Beauty() {}
Beauty(const Beauty& other) {}
};
//c++二进制拷贝
void cppCopyBinary(const char* dest, const char* src) {//无法检测是否出现错误..
std::ifstream input(src, ios::binary);
std::ofstream output(dest, ios::binary);
output << input.rdbuf();// read binary读取input
}
//c二进制拷贝
string cCopyBinary1(const char* dest, const char* src) {
FILE* destF_p = NULL, * srcF_p = NULL;
fopen_s(&srcF_p, src, "rb");// read binary
if (!srcF_p) {
return "源文件打开失败!";
}
fopen_s(&destF_p, dest, "wb");// write binary
if (!destF_p) {
fclose(srcF_p);
return "目标文件打开失败!";
}
char buffer[BUFFER_SIZE];
int readLen = fread_s(buffer, BUFFER_SIZE, ELEMENT_SIZE, BUFFER_SIZE, srcF_p);
if (readLen <= 0) {
fclose(srcF_p);
fclose(destF_p);
return "源文件读取失败!";
}
int writeLen = fwrite(buffer, ELEMENT_SIZE, readLen, destF_p);
if (readLen != writeLen) {
fclose(srcF_p);
fclose(destF_p);
return "目标文件拷贝失败!";
}
fclose(srcF_p);
fclose(destF_p);
return "成功!";
}
void cCopyBinary2(const char* dest, const char* src) {
FILE* destF_p = NULL, * srcF_p = NULL;
fopen_s(&srcF_p, src, "rb");
if (!srcF_p) {
throw "源文件打开失败!";
}
fopen_s(&destF_p, dest, "wb");
if (!destF_p) {
fclose(srcF_p);
throw "目标文件打开失败!";
}
char buffer[BUFFER_SIZE];
int readLen = fread_s(buffer, BUFFER_SIZE, ELEMENT_SIZE, BUFFER_SIZE, srcF_p);
if (readLen <= 0) {
fclose(srcF_p);
fclose(destF_p);
throw "源文件读取失败!";
}
int writeLen = fwrite(buffer, ELEMENT_SIZE, readLen, destF_p);
if (readLen != writeLen) {
fclose(srcF_p);
fclose(destF_p);
throw "目标文件拷贝失败!";
}
fclose(srcF_p);
fclose(destF_p);
throw "成功!";
}
void cCopyBinary3(const char* dest, const char* src) throw(char, int)//最好异常接口声明下,虽然C11编译器检测不出来!但可以起到提示/保证作用
{
FILE* destF_p = NULL, * srcF_p = NULL;
fopen_s(&srcF_p, src, "rb");
if (!srcF_p) {
//throw Beauty();
throw string("源文件打开失败!");
}
fopen_s(&destF_p, dest, "wb");
if (!destF_p) {
fclose(srcF_p);
throw new string("目标文件打开失败!");
}
char buffer[BUFFER_SIZE];
int readLen = fread_s(buffer, BUFFER_SIZE, ELEMENT_SIZE, BUFFER_SIZE, srcF_p);
if (readLen <= 0) {
fclose(srcF_p);
fclose(destF_p);
throw new string("源文件读取失败!");
}
int writeLen = fwrite(buffer, ELEMENT_SIZE, readLen, destF_p);
if (readLen != writeLen) {
fclose(srcF_p);
fclose(destF_p);
throw - 1;
}
fclose(srcF_p);
fclose(destF_p);
throw 0;
}
//可以多次扔
void twoTimes() {
try {
cCopyBinary1("D:/tmp/dest.txt", "D:/tmp/src.txt");
}
catch (...) {
throw;
}
}
int main() {
cppCopyBinary("dest.txt", "src.txt");
cout << cCopyBinary1("D:/tmp/dest.txt", "D:/tmp/src.txt") << endl;//注意只有硬盘名后加冒号
cout << "throw char,形参char*,实参char*申请内存,被赋值:" << endl;
try {
twoTimes();
}
catch (const char* err) {// "xxxx"传递值类型为char不能传给string
cerr << err << endl;
}
cout << "throw new string/new char(char),形参string*,直接输出:";//创建new异常元素
try {
cCopyBinary3("D:/tmp/dest.txt", "D:/tmp/src.txt");
}
catch (Beauty& beauty) {
cout << "捕捉到类Beauty异常!" << endl;
}
catch (string* err) {//err相当于处于缓冲区,需要再分配动态内存至error
cout << "捕捉到字符串异常:" << err->c_str() << endl;
delete err;
}
catch (int n) {
if (!n) {//数字可直接传值
cout << "捕捉到数字0:" << "成功!" << endl;
}
}
catch (string err)
{
cout << "捕捉到string异常" << endl;
}
return 0;
}
//最佳方式:int直接扔
//字符串直接"xxx",const char*接 (也可string()初始化,string接;若new string初始化,string *接,需记得再delete err;)
//类直接Beauty()初始化,Beauty&接; (若new Beauty则指针接,记得释放)
三个函数的区别:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-elmPEvuL-1587300702380)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20200419203253574.png)]
接"xxx",const char*接 (也可string()初始化,string接;若new string初始化,string *接,需记得再delete err;)
//类直接Beauty()初始化,Beauty&接; (若new Beauty则指针接,记得释放)
三个函数的区别:
![在这里插入图片描述](https://img-blog.csdnimg.cn/202004192052062.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FpbnU0MTI=,size_16,color_FFFFFF,t_70)