> 文章列表 > C++中的异常

C++中的异常

C++中的异常

C++中的异常主要由三个关键字构成:try,catch,throw
其中throw抛出异常,try包围可能发生异常的语句,catch用来做异常处理。
看一个例子:

#include <iostream>
#include <string>
using namespace std;int main()
{try {throw(string("gaoyuelong"));}catch (string str) {cout << str << endl;}return 0;
}

throw可以抛出任意异常,只要catch进行相应的捕获即可。
比如:

int main() {int age = 100;try {if (age > 90) {throw(age);//throw后面的语句不会被执行到cout << "123" << endl;}}catch (int age) {cout << age << " is too big" << endl;}return 0;
}

上面的例子中提到throw后面的语句不会被执行值得注意。

异常会向外传播,直到有相应的catch捕获异常,比如:

void inner()
{//在外层被捕获throw("123");
}void outer()
{try{inner();}catch (...){cout << "exception caught" << endl;}
}int main()
{outer();return 0;
}

如果一直向外传播都没有找到匹配的catch捕获,程序会崩溃。catch(...)表示捕获任意类型的异常。

如果我们想在抛出异常时,携带一些信息,帮助开发人员更好的调用调试,可以继承自exception类,重写what方法:

class idontknowwhatshappening : public exception
{
public:idontknowwhatshappening() = default;~idontknowwhatshappening() = default;idontknowwhatshappening& operator=(const idontknowwhatshappening&) = default;//返回const char*而不是string,string可能也会发生异常const char* what() { return "I don't know what's happening"; };
};void inner()
{try{throw(idontknowwhatshappening());}catch (idontknowwhatshappening &e){cout << e.what() << endl;}
}void outer()
{try{inner();}catch (...){cout << "exception caught" << endl;}
}

异常被捕获时,会按照catch定义的语句顺序,挨个进行匹配,执行第一个匹配完成的流程:

class idontknowwhatshappening : public exception
{
public:idontknowwhatshappening() = default;~idontknowwhatshappening() = default;idontknowwhatshappening& operator=(const idontknowwhatshappening&) = default;const char* what() const { return "I don't know what's happening"; };
};void inner()
{try{throw(idontknowwhatshappening());}catch (const idontknowwhatshappening &e){//匹配到则先执行这里cout << e.what() << endl;}catch (exception &e){cout << "e" << endl;}//而如果父类exception先进行捕获的话,就先执行父类的捕获//catch按顺序执行,他会执行第一个能匹配到的捕获/*catch (exception &e){cout << "e" << endl;}catch (const idontknowwhatshappening &e){cout << e.what() << endl;}*/
}

如果异常在被第一个catch捕获时,需要修改对象的值,这时需要引用对象:

class i : public exception
{
public:i() = default;~i() = default;i& operator=(const i&) = default;const char* what() { return "exception i"; }string s;
};void outer()
{try{throw i();}catch (i& I)//这里使用引用{I.s = "123";cout << "exception caught" << endl;cout << I.s << endl;}
}

若当前catch发现处理不了异常,需要继续向上传递时,使用throw

void outer()
{try{throw i();}catch (i& I){I.s = "123";cout << "exception caught" << endl;cout << I.s << endl;//继续向上层抛出throw;}
}int main() {try{outer();}catch (i &I){cout << "main: " << I.s << endl;}return 0;
}

如果一个函数我们确保他不会发生异常,可以使用noexcept关键字,这样编译器可能会对这个函数做一些不会抛出异常的优化

//用noexcept修饰后,不能再抛出异常了,否则程序会崩溃
const char* foo() noexcept
{throw("123");
}int main() 
{try {foo();}catch (...){cout << "exception caught" << endl;}return 0;
}

关于异常的编码规范,一般关于异常的处理都放在外面做,而函数自身,只需要进行检查,若不符合规范抛出异常让外层处理。比如:

void Process(int n)
{if (n > 3){//去外面处理,不要在使用方处理throw runtime_error("number too big");}
}int main() 
{vector<int> v = {1, 2, 3, 4, 5};for (int i = 0; i < 5; i++){try {Process(v[i]);cout << v[i] << endl;}catch(runtime_error &e){cout << e.what() << endl;}}return 0;
}

以上,便是对C++中异常的一些基础使用,希望对你有用。

如果你觉得文章还不错,欢迎点赞评论哦!关注账号,你还会收到关于C++的更多知识哦!!