异常机制
- c++异常机制是跨函数的,且必须处理
XXX fun1(int x)
{
throw x; //抛出异常n'g
}
XXX fun2()
{
fun1(0);
}
XXX fun3()
{
try //尝试捕获大括号内代码的异常
{
fun2();
}
catch(int e) //异常时根据类型进行匹配,此处以 int 为例,与抛出的异常类型相匹配
{
... //对捕获到的异常的处理
}
catch(XXX e) //后面可以有多个 catch
{
...
}
catch(...) //此处 ... 不是省略了某条语句,就是这么个写法,代表所有异常 或者所有未发现异常
{
...
}
}
- 异常接口声明
void func1() throw(int, float, char) //这个函数只能抛出 int flaot char 类型的异常
{
throw XXX;
}
void func2() throw() //不能抛出任何异常
{
throw -1;
}
void func3() //抛出所有异常
{
throw XXX;
}
- c++异常库继承关系图
-
标准的异常库有限,要学会编写自己的异常类
建议自己的异常类要继承标准的异常类,c++中可以抛出任何类型的异常,如果不继承的话可能会出现错误
当继承标准异常类时,要重载父类的what函数和虚析构函数
//以out_of_range为例
#include<iostream>
#include<stdexcept>
using namespace std;
class Person
{
public:
Person() { m_Age = 0; }
void setAge(int age)
{
if (age < 0 || age > 100)
{
throw out_of_range("年龄应该在0-100之间"); //抛出异常
}
this->m_Age = age;
}
public:
int m_Age;
};
void test01()
{
Person p;
try
{
p.setAge(10000); //设置年龄为10000岁
}
//catch(exception e) logic_error 的父类
//catch(logic_error e) out_of_range 的父类
//以上两种写法加上下面的写法都可以
catch (out_of_range e)
{
cout << e.what() << endl;
}
}
//----------------------------------------------------------------------
class MyOutOfRange:public exception // MyOutOfRange
{
public:
MyOutOfRange(char* error)
{
pError = new char[strlen(error) + 1];
strcpy(pError, error);
}
~MyOutOfRange()
{
if (pError != NULL)
{
delete[] pError;
}
}
virtual const char* what() const // what()
{
return pError;
};
private:
char* pError;
};
void fun02()
{
//以下内容在VS2019里面直接写成
//throw MyOutOfRange("My out_of_range! ");
//会报参数不匹配的错误
char c[] = "My out_of_range! ";
char* ch = c;
throw MyOutOfRange(ch);
}
void test02()
{
try
{
fun02();
}catch(MyOutOfRange& e)
{
cout << e.what() << endl;
}
}
int main()
{
test01();
test02();
return 0;
}
年龄应该在0-100之间
My out_of_range
- 继承在异常中的运用
#include<iostream>
using namespace std;
//异常基类
class BaseMySpaceNullException
{
public:
virtual void what() = 0;
~BaseMySpaceNullException() {};
};
//目标空间异常类
class TargetSpaceNullException:public BaseMySpaceNullException
{
public:
virtual void what()
{
cout << "目标空间为空!" << endl;
}
~TargetSpaceNullException() {};
};
//源空间异常类
class SourceSpaceNullException :public BaseMySpaceNullException
{
public:
virtual void what()
{
cout << "源空间为空!" << endl;
}
~SourceSpaceNullException() {};
};
//字符串拷贝函数
void CopyStr(char* target, char* source)
{
if (target == NULL) //判断目标空间是否为空
{
cout << "目标空间为空!" << endl;
return;
}
if (source == NULL) //判断源空间是否为空
{
cout << "源空间为空!" << endl;
return;
}
while (*source != '\0') //实现字符串拷贝功能
{
*target = *source;
target++;
source++;
}
}
int main()
{
char ch[] = "qwert";
char* source = ch;
char buf[1000] = { 0 };
try
{
CopyStr(buf, source); //调用字符串拷贝函数
}
catch (BaseMySpaceNullException& e) //直接写基类异常就可以不用写好几个catch
{
e.what();
}
cout << buf << endl;
return 0;
}