C++ 关于异常捕获的槽点

可能用到的头文件先列出来:

#include <vector>
#include <exception>
#include <excpt.h>  
#include <cassert>
#include <windows.h>
using namespace std;

本来想要一个像.net那样的异常捕获try{}catch(Exception ex){//"几乎能够捕获各种异常,只需要将ex里面的信息写到日志里面就行了,看看日志就知道问题大概在哪里"};感觉.net还是挺方便的与是相当然的想在C++的项目里也这样做,然后发现事实并不行。

首先,C++里面的异常类关系是这样的

详细的说明可以看菜鸟教程,我经常看。哈哈哈哈。

C++ 异常处理 | 菜鸟教程

我的目的就是把异常写到本地日志,所以我就不关心这么多继承了,直接使用基类std::exception;

记得添加#include<exception>;

于是,我写了下面的代码:

int a=0;
int b=2;
int c=b/a;//0不能作为分母,这里肯定会抛出异常,来捕获它吧

神奇的事情发生了,没有捕获到异常。

是我.net思想太严重了。于是,使用了下面的代码,但是,不满足我的需求啊

try {
		int a = 0;
		int b = 2;
		int c = b / a;//0不能作为分母,这里肯定会抛出异常,来捕获它吧
	}
	catch (...) {
		//这里我获取不到有用的异常提示信息啊,我该向日志里写啥呢?
	}

以上代码确实可以捕获到异常但是还是先进行一个项目属性的设置,注意是项目属性:

还有我也不知道应该把什么异常信息写给日志。

所以,这样肯定是不行的。但是,有些异常时可以的,例如:

try
	{
		v.at(100) = 100;  //拋出 out_of_range 异常
	}
	catch (const std::exception& e)
	{
		//里面有异常信息是这样的:invalid vector subscript;这个信息还算有点用
        std::string meg=e.what();
	}

我的日志是需要给std::exception 类型的参数的,所以你必须给我这个类型的对象。那对于不能捕获到异常的除零这样的怎么办呢?

于是,我自己做了一个继承std::exception 类的自定义异常类并重写了what();如下:

这是用的类:

class MyException:public std::exception
{
public :
	MyException();
	~MyException();
	const char* what() const noexcept /*noexcept*/ override { return "发生异常了"; }
};
MyException::MyException()
{

};
MyException::~MyException()
{

};

使用结构体也可以:

struct MyException: std::exception {
	const char* what() const noexcept { return "发生异常了"; }
};

无论是类还是结构体对exception做了继承。用法都如下:

try
	{
	    int a = 0;
		int b = 2;
		if (a==0)
		{
            //用惯了.net真心不能接受这样的设计,都判断出来了还抛异常干嘛呢?但是为了写到日志里
            //也是改变自己了
			throw MyException();
		}
        //因为上面throw了,这里就不会走了
		int c = b / a;//0不能作为分母,上面提前捕获了
	}
	catch (const std::exception& e)
	{
       //成功进到这里并且还是exception类型,meg就是上面重写的值。
		std::string meg=e.what();
	}

到此为止,已经满足我写日志的需求了。但是,需要开发者去重写exception,还是知道在哪里需要抛出异常,还需要自己设置异常信息。

下面做个优化给MyException加了一个构造的重载:

class MyException :public std::exception
{
public:
	MyException();
	MyException(std::string _meg);
	~MyException();
	const char* what() const noexcept /*noexcept*/ override { return meg.c_str(); }
private:
	string meg;
};
MyException::MyException()
{

};

MyException::MyException(std::string _meg)
{
   //设置异常提示信息
	meg = _meg;
};

MyException::~MyException()
{

};

这样使用重载的构造函数就可以动态设置异常的提示信息了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值