首页 / C++ / 【12】C++进阶系列(异常处理)
【12】C++进阶系列(异常处理)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了【12】C++进阶系列(异常处理),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3929字,纯文字阅读大概需要6分钟。
内容图文
容错性:
1、我们希望使用者有试错的机会,能够继续运行,而不希望一旦出错就退出。如果没有这种操作,我们也需要将出错的消息反馈给使用者。
当发生异常的时候可以选择就地处理,但也可以选择不就地处理。抛出异常再处理就是后者。有些就地处理会影响到程序的主逻辑,而且有地模块是最底层的模块,它是没有办法知道该如何处理这个异常的,所以需要抛出异常给调用者,由调用者捕获并选择是否处理。
各种步骤都判断成功与否,或者要输出反馈,这对于程序的主逻辑是不利的。
将有可能发生异常的情况都放在了try模块中,并尝试处理(不处理或者抛出)。
异常处理模块是我们可以专注程序的主逻辑。
2、异常处理:抛出、捕获、处理。
异常的抛出都是向他的上级调用者,异常处理的基本思想:
这样的级层关系,使得可以在不同的位置处理不同的异常,方便我们专注于程序主逻辑的设计。
异常处理的语法:抛出和捕获的配合
例子:除数为0的异常
#include<iostream>
using namespace std;
int divide(int x, int y) {
if (y==0)
{
throw x;
}
return x / y;
}
int main() {
try
{
cout << "5/2=" << divide(5, 2) << endl;
cout << "8/0=" << divide(8, 0) << endl;
cout << "7/1=" << divide(7, 1) << endl;
}
catch (int e)
{
cout << e << "is divided by zero!" << endl;
}
cout << "That is ok." << endl;
return 0;
}
异常接口声明:
可以在函数的声明中列出这个函数可能抛出的异常类型。例如:void fun() throw(A,B,C,D);
若无异常接口声明,则表示此函数可以抛出任何类型的异常。
肯定不抛出任何类型异常的函数声明如下:void fun() throw();括号里面没有任何参数
3、异常处理中的构造和析构
问题:抛出异常之后,throw语句后面的语句不再执行,当前程序块没有执行到 “}”的部分,所以当前“{ ……}”中的函数没有被析构。那么是怎样的机制来处理这部分的析构呢?——自动的析构
找到一个匹配的catch异常处理之后:
初始化异常参数
将对应的try块开始到异常被抛出处之间构造(且尚未析构)的所有自动对象进行析构。
从最后一个catch处理之后开始恢复执行。
比如:抛出一场之后Demo d是怎么析构的呢?
#include<iostream>
#include<string>
using namespace std;
class MyException
{
public:
MyException(const string & message):message(message){}
~MyException() {}
const string &getMessage()const { return message; }
private:
string message;
};
class Demo
{
public:
Demo() { cout << "Constructor of demo." << endl; }
~Demo() { cout << "Destructor of demo" << endl; }
private:
};
void func() throw(MyException) {
Demo d;
cout << "Throw MyException in func()" << endl;
throw MyException("exception thrown by func()");//这时d还没有析构,中途抛出异常终止了函数的执行,此时程序回到调用者(主函数func())
} //执行到这里d才会析构
int main() {
cout << " In main function" << endl;
try
{ //异常处理机制保证进入try之后,抛出异常之前构造的对象 d 析构完成。然后才进入catch块里面处理异常
func();
}
catch (MyException &e)
{
cout << "Caught an exception:" << e.getMessage() << endl;
}
cout << "Resume the execution of main()" << endl;
return 0;
}
4、标准程序库异常处理
继承关系:exception是所有异常类的基类
异常类:
标准异常类的基础:
exception:标准程序库异常类的公共基类
logic_error:表示可以在程序中被预先检测到的异常。如果小心的写程序,这类异常能够避免
runtime_error:表示难以被预先估计检测的异常。
例子:求解三角形面积
#include<iostream>
#include<cmath>
#include<stdexcept>//向函数传入了无效参数(invalid_argument)的头文件
using namespace std;
double area(double a, double b, double c) throw(invalid_argument) {
//判断三角形边长是否为正
if (a<0|b<0|c<0)
{
throw invalid_argument("the side length should be positive");
}
//判断三边长是否能构成三角形
if (a+b<=c||a+c<=b||b+c<=a)
{
throw invalid_argument("the side length should fit the triangle inequation");
}
//由Heron公式计算三角形面积
double s = (a + b + c) / 2.0;
cout<<sqrt(s*(s - a)*(s - b)*(s - c));
}
int main() {
double a, b, c;
cout << "Please input the side length of a triangle:" << endl;
cin >> a >> b >> c;
try
{
area(a, b, c);
}
catch (exception &e)
{
cout << "Error:" << e.what() << endl;
}
return 0;
}
************************************************************************************************
写在最后,整个系列看完。刚好一个月
人艰不拆
内容总结
以上是互联网集市为您收集整理的【12】C++进阶系列(异常处理)全部内容,希望文章能够帮你解决【12】C++进阶系列(异常处理)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。