C++异常概念 异常是一种处理错误的方式,当一个函数发现自己无法处理的错误时就可以抛出异常,让函数的直接或间接的调用者处理这个错误。
throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。
catch: 在想要处理问题的地方,通过异常处理程序捕获异常.catch 关键字用于捕获异常,可以有多个catch进行捕获。
try: try 块中的代码标识将被激活的特定异常,它后面通常跟着一个或多个 catch 块。 如果有一个块抛出一个异常,捕获异常的方法会使用 try 和 catch 关键字。try 块中放置可能抛出异常的代码,try 块中的代码被称为保护代码。
当发生异常后,执行会直接跳到与之匹配的catch语句,当返回到mian()都没找到匹配的catch()语句,则终止程序。
void fun3()
{
int b = 0;
if ( b == 0)
{
throw "bad";
}
cout << "fun3()" << endl;
}
void fun2()
{
fun3();
cout << "fun2()" << endl;
}
void fun1()
{
fun2();
cout << "fun1()" << endl;
}
void test5()
{
try
{
fun1();
}
catch (...)
{
cout << "异常!!!" << endl; // 一旦抛出异常,立刻跳到catch接收异常,停止其他操作
}
}
结果:
异常!!! // 直接打印了异常
1.异常是通过抛出对象而引发的,该对象的类型决定了应该激活哪个catch的处理代码。
2. 被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那一个。
3. 抛出异常对象后,会生成一个异常对象的拷贝,因为抛出的异常对象可能是一个临时对象,所以会生成一个拷贝对象,这个拷贝的临时对象会在被catch以后销毁。
4. catch(...)可以捕获任意类型的异常,不知道异常错误是什么。
5. 实际中抛出和捕获的匹配原则有个例外,并不都是类型完全匹配,可以抛出的派生类对象,使用基类捕获。
class parent
{
public:
parent(const string& errmsg,int id)
:_errmsg(errmsg)
,_id(id)
{ }
virtual string what() = 0;
protected:
string _errmsg; // 错误描述
int _id; // 错误码
};
class ch1 :public parent
{
public:
ch1(const string& errmsg, int id)
:parent(errmsg,id)
{ }
virtual string what()
{
return "错误码: " + _errmsg + " id: " + to_string(_id);
}
};
class ch2 :public parent
{
public:
ch2(const string& errmsg, int id)
:parent(errmsg, id)
{
}
virtual string what()
{
return "错误码: " + _errmsg + " id: " + to_string(_id);
}
};
class ch3 :public parent
{
public:
ch3(const string& errmsg, int id)
:parent(errmsg, id)
{
}
virtual string what()
{
return "错误码: " + _errmsg + " id: " + to_string(_id);
}
};
void test()
{
if (rand() % 3)
{
throw ch1("ch1错误", 123);
}
if (rand() % 7)
{
throw ch2("ch2错误", 456);
}
if (rand() % 2)
{
throw ch3("ch3错误", 789);
}
}
void test3()
{
for (int i = 0; i < 100; i++)
{
try
{
test();
}
catch (parent& p) // ---> 子类转化为父类类型 // 构成多态
{
cout << p.what() << endl;
}
catch (...)
{
cout << "未知异常" << endl;
}
}
}