18. 异常
异常:错误,意料之外的情况
常见的错误处理方法:
1.全局错误码
给每个错误定义一个错误码,赋值给全局变量
int n_gError
例如C语言库和windows编程的GetLastError()
缺点:维护困难
2.函数返回值
例如成功返回0,失败返回1...
缺点:函数调用层次多时,内层函数调用出错,错误码返回外层比较难设计。
例如调用链A->B->C->D->E,E错出错了,要依次返回到A
3.异常
int main() {
throw 1;//如果异常没有被处理,最终会调用abort(),Debug版还会弹窗
cout << "asdf";
return 0;
}
int main() {
//类型必须精确匹配,不会隐式转换
try {
throw 1;//1是int类型
}
catch (unsigned i) {//类型不匹配
cout << i;
}
catch (double d) {//类型不匹配
cout << d;
}
//最终没有被捕获,调用abort()
return 0;
}
int main() {
try {
throw 1;
cout << 1234;//不会执行这句,因为上面抛出了异常,之前的结果有问题,继续使用则可能发生问题
}
catch (int i) {
cout << i;
}
catch (...) {//捕获任何类型异常
}
cout << 5678;//会执行,因为异常已经处理了
return 0;
}
构造析构中抛出异常:
class A {
public:
A() {
cout << "A" << endl;
//throw 1;//构造函数中抛异常,不会调用析构函数
}
~A() {
throw 1;
cout << "~A" << endl;//不走catch块,直接调用abort()
}
};
int main() {
try {
A a;//离开try,进入catch时会调用析构函数
throw 1;
cout << 1234;//不会执行这句,因为上面抛出了异常,之前的结果有问题,继续使用则可能发生问题
}
catch (int i) {
cout << i;
}
return 0;
}
异常常用模式:从父类异常继承
class ExceptionInfo {
public:
ExceptionInfo(string file, string func, int line, string msg) :
fileName(file), funcName(func), lineNumber(line), errorMsg(msg) {}
string GetFileName()const { return fileName; }
string GetFuncName()const { return funcName; }
size_t GetLineNumber()const { return lineNumber; }
string GetErrorMsg()const { return errorMsg; }
private:
string fileName;
string funcName;
size_t lineNumber;
string errorMsg;
};
class AddOverflowExceptionInfo :public ExceptionInfo {
public:
AddOverflowExceptionInfo(string file, string func, int line, string msg) :
ExceptionInfo(file, func, line, "加法溢出") {
}
private:
};
void f() {
throw AddOverflowExceptionInfo(__FILE__, __func__, __LINE__, "错误");
}
int main() {
try {
f();
}
catch (const ExceptionInfo & e) {
cout << e.GetFileName() << endl
<< e.GetFuncName() << endl
<< e.GetLineNumber() << endl
<< e.GetErrorMsg() << endl;
}
return 0;
}

浙公网安备 33010602011771号