首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >C++自定义异常案例

C++自定义异常案例

原创
作者头像
软件架构师Michael
发布2023-08-20 21:44:25
发布2023-08-20 21:44:25
4950
举报

C++ 标准异常

C++ 在 <exception> 中提供了一系列标准的异常,我们可以用在我们的程序中。这些异常使用父-子分层结构展示如下:

异常分层结构
异常分层结构

这是对上面提到的层次结构中每个异常的描述:

  • std::exception
  • 异常和所有标准 C++ 异常的父类。
  • std::bad_alloc
  • 该异常可能会在使用 new 关键字时抛出。
  • std::bad_cast
  • 该异常可以由 dynamic_cast 抛出。
  • std::bad_exception
  • 这是一个在 C++ 程序中处理意想不到的异常的有效手段。
  • std::bad_typeid
  • 该异常可以由 typeid 抛出。
  • std::logic_error
  • 理论上可以通过阅读代码发现的异常。
  • std::domain_error
  • 这是一个在数学无效域被使用时抛出的异常。
  • std::invalid_argument
  • 参数非法时会抛出的异常。
  • std::length_error
  • 太大的 std::string 被创造时,抛出异常。
  • std::out_of_range
  • 可以抛出该异常的方法例如 std::vectorstd::bitset::operator[]()
  • std::runtime_error
  • 理论上不能通过读代码检测到的异常。
  • std::overflow_errorr
  • 如果出现数字溢出,则抛出该异常。
  • std::range_error
  • 当你试图存储一个超过范围的值的时候,会抛出该异常。
  • std::underflow_error
  • 如果出现数学下溢时,抛出该异常。

定义新异常

你可以采用继承及重写异常类来。下面是示例,显示如何使用 std::exception 类以标准的方式实现自己的异常:

代码语言:javascript
复制
#include <iostream>
#include <exception>
using namespace std;

struct MyException : public exception {
  const char * what() const throw() {
    return "C++ Exception";
  }
};

int main() {
  try {
    throw MyException();
  } catch(MyException& e) {
    std::cout << "MyException caught" << std::endl;
    std::cout << e.what() << std::endl;
  } catch(std::exception& e) {
    //Other errors
  }
}

这将产生如下的结果:

代码语言:javascript
复制
MyException caught
C++

这里,what()是一个异常类提供的公共方法,所有子异常类都覆盖了该方法。这将返回一个异常的原因。

项目过程中的自定义异常案例

代码语言:javascript
复制
#include <iostream>
#include <Windows.h>
#include <exception>
using namespace std;
// 服务器开发中通常使用的异常继承体系
class Exception
{
public:
	Exception(const string& errmsg, int id)
		:_errmsg(errmsg)
		, _id(id)
	{}
	virtual string what() const
	{
		return _errmsg;
	}
protected:
	string _errmsg;
	int _id;
};
class SqlException : public Exception
{
public:
	SqlException(const string& errmsg, int id, const string& sql)
		:Exception(errmsg, id)
		, _sql(sql)
	{}
	virtual string what() const
	{
		string str = "SqlException:";
		str += _errmsg;
		str += "->";
		str += _sql;
		return str;
	}
private:
	const string _sql;
};
class CacheException : public Exception
{
public:
	CacheException(const string& errmsg, int id)
		:Exception(errmsg, id)
	{}
	virtual string what() const
	{
		string str = "CacheException:";
		str += _errmsg;
		return str;
	}
};
class HttpServerException : public Exception
{
public:
	HttpServerException(const string& errmsg, int id, const string& type)
		:Exception(errmsg, id)
		, _type(type)
	{}
	virtual string what() const
	{
		string str = "HttpServerException:";
		str += _type;
		str += ":";
		str += _errmsg;
		return str;
	}
private:
	const string _type;
};
void SQLMgr()
{
	srand(time(0));
	if (rand() % 7 == 0)
	{
		throw SqlException("权限不足", 100, "select * from name = '张三'");
	}
	//throw "xxxxxx";
}
void CacheMgr()
{
	srand(time(0));
	if (rand() % 5 == 0)
	{
		throw CacheException("权限不足", 100);
	}
	else if (rand() % 6 == 0)
	{
		throw CacheException("数据不存在", 101);
	}
	SQLMgr();
}
void HttpServer()
{
	// ...
	srand(time(0));
	if (rand() % 3 == 0)
	{
		throw HttpServerException("请求资源不存在", 100, "get");
	}
	else if (rand() % 4 == 0)
	{
		throw HttpServerException("权限不足", 101, "post");
	}
	CacheMgr();
}
int main()
{
	while (1)
	{
		try
		{
			HttpServer();
		}
		catch (const Exception& e) // 这里捕获父类对象就可以
		{
			// 多态
			cout << e.what() << endl;
			Sleep(1000);
		}
		catch (...)
		{
			cout << "Unkown Exception" << endl;
		}
	}
	return 0;
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C++ 标准异常
  • 定义新异常
  • 项目过程中的自定义异常案例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档