目录
1、C语言传统的错误处理方式
2、C++异常概念
3、异常的用法
3.1、异常的抛出与捕获
3.1.1、在函数调用链中异常栈展开匹配原则
3.1.2、异常的抛出和匹配原则
3.3、异常规范
3.4、异常的重新抛出
4、自定义异常体系
只有抛异常才会执行catch,否则不会执行;catch匹配的是就近原则。catch执行完之后面的代码正常执行。
double Division(int a, int b)
{
// 当b == 0时抛出异常
if (b == 0)
{
throw "Division by zero condition!";
}
return (double)a / (double)b;
}
void Func()
{
// 这里可以看到如果发生除0错误抛出异常,另外下面的array没有得到释放。
// 所以这里捕获异常后并不处理异常,异常还是交给外面处理,这里捕获了再
// 重新抛出去。
int* array = new int[10];
try {
int len, time;
cin >> len >> time;
cout << Division(len, time) << endl;
}
catch (...) //有除0错误,所以它来捕获,但是它不处理异常 只是先将内存释放
//释放完之后再将异常抛出交给外部
{
cout << "delete []" << array << endl;
delete[] array;
throw; //异常重新抛出
}
// ...
cout << "delete []" << array << endl;
delete[] array;
}
int main()
{
try
{
Func();
}
catch (const char* errmsg) //接受到重新抛出的异常
{
cout << errmsg << endl; //对异常进行处理
}
return 0;
}
class Exception //基类
{
public:
Exception(const string& errmsg, int id)
:_errmsg(errmsg)
,_id(id)
{}
virtual string what() const
{
return _errmsg;
}
protected:
string _errmsg;
int _id;
};
class SqlException : public Exception //sql类
{
public:
SqlException(const string& errmsg, int id, const string& sql)
:Exception(errmsg, id)
, _sql(sql)
{}
virtual string what() const
{
string str = "SqlException:";
str += _errmsg;
str += "->";
str += _sql;
return str;
}
private:
const string _sql;
};
class CacheException : public Exception //cache模块
{
public:
CacheException(const string& errmsg, int id)
:Exception(errmsg, id)
{}
virtual string what() const
{
string str = "CacheException:";
str += _errmsg;
return str;
}
};
class HttpServerException : public Exception //http模块
{
public:
HttpServerException(const string& errmsg, int id, const string& type)
:Exception(errmsg, id)
, _type(type)
{}
virtual string what() const
{
string str = "HttpServerException:";
str += _type;
str += ":";
str += _errmsg;
return str;
}
private:
const string _type;
};
void SQLMgr() //sql模拟错误
{
srand(time(0));
if (rand() % 7 == 0)
{
throw SqlException("权限不足", 100, "select * from name = '张三'");
}
//throw "xxxxxx";
}
void CacheMgr() //cache模拟错误
{
srand(time(0));
if (rand() % 5 == 0)
{
throw CacheException("权限不足", 100);
}
else if (rand() % 6 == 0)
{
throw CacheException("数据不存在", 101);
}
SQLMgr();
}
void HttpServer() //http模拟错误
{
// ...
srand(time(0));
if (rand() % 3 == 0)
{
throw HttpServerException("请求资源不存在", 100, "get");
}
else if (rand() % 4 == 0)
{
throw HttpServerException("权限不足", 101, "post");
}
CacheMgr();
}
int main()
{
while (1)
{
this_thread::sleep_for(chrono::seconds(1));
try{
HttpServer();
}
catch (const Exception& e) // 这里捕获父类对象就可以
{
// 多态 直接利用多态 就可以捕获不同类型的异常
cout << e.what() << endl;
}
catch (...)
{
cout << "Unkown Exception" << endl;
}
}
return 0;
}