最近更新于 2024-05-05 14:18
环境
Debian 11(arm64)
编译器 g++ 10.2.1;编译标准 C++20;参数:-std=c++20 -no-pie -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Werror=format-security -Wextra -pedantic -Wimplicit-fallthrough -Wsequence-point -Wswitch-unreachable -Wswitch-enum -Wstringop-truncation -Wbool-compare -Wtautological-compare -Wfloat-equal -Wshadow=global -Wpointer-arith -Wpointer-compare -Wcast-align -Wcast-qual -Wwrite-strings -Wdangling-else -Wlogical-op -Wconversion -g -O0
抛出异常消息
#include <iostream>
int main()
{
try
{
int x = 10;
int y = 0;
if (y == 0)
{
throw "除数为 0";
}
std::cout << x / y << std::endl;
}
catch (const char *msg)
{
std::cerr << "捕获到异常:" << msg << std::endl;
}
catch (...)
{
std::cerr << "未知异常" << std::endl;
}
}
标准异常
标准异常类
std::bad_alloc:当动态内存分配失败时,会抛出该异常。
std::bad_cast:当使用dynamic_cast转换失败时,会抛出该异常。
std::logic_error:表示程序逻辑错误,包括以下几个子类:
std::invalid_argument:当传递给函数的参数无效时,会抛出该异常。
std::domain_error:当数学函数的参数超出定义域时,会抛出该异常。
std::length_error:当试图创建一个超出允许范围的字符串或容器时,会抛出该异常。
std::out_of_range:当索引超出有效范围时,会抛出该异常。
std::runtime_error:表示运行时错误,包括以下几个子类:
std::overflow_error:当计算结果超出了数值类型的范围时,会抛出该异常。
std::underflow_error:当计算结果小于数值类型的最小值时,会抛出该异常。
std::range_error:当某个计算结果超出了数值类型的可表示范围时,会抛出该异常。
std::system_error:表示底层操作系统或库函数返回错误代码时,会抛出该异常。
#include <iostream>
#include <exception>
int main()
{
try
{
int x = 10;
int y = 0;
if (y == 0)
{
throw std::runtime_error("除数为 0");
}
std::cout << x / y << std::endl;
}
catch (const std::exception &e)
{
std::cerr << "捕获到异常:" << e.what() << std::endl;
}
}
自定义异常类
自定义异常
#include <iostream>
#include <exception>
class MyException : public std::exception
{
public:
virtual const char *what() const noexcept
{
return "这是一个自定义异常";
}
};
int main()
{
try
{
throw MyException();
}
catch (const std::exception &e)
{
std::cerr << "捕获到异常:" << e.what() << std::endl;
}
}
自定义异常虚析构的使用
这里假定一个情景,抛出自定义的异常对象后,首先打开(或创建)一个错误日志文件,并往里面追加错误信息,同时将错误信息返回给捕获错误处,自定义异常对象寿命终止,虚析构检查错误日志文件是否关闭,没有关闭就关闭文件。
#include <iostream>
#include <fstream>
#include <exception>
class MyException : public std::exception
{
public:
MyException(const char *message, const char *file) : msg(message), filename(file)
{
log();
}
virtual ~MyException() noexcept
{
if (logFile.is_open())
{
logFile.close();
}
}
virtual const char *what() const noexcept
{
return msg.c_str();
}
void log()
{
logFile.open(filename, std::ios::out | std::ios::app);
if (logFile.is_open())
{
logFile << msg << std::endl;
logFile.close();
}
}
private:
std::string msg;
std::string filename;
std::ofstream logFile;
};
int main() {
try
{
throw MyException("出现 XXX 错误", "error.log");
}
catch (const std::exception &e)
{
std::cerr << "捕获到异常:" << e.what() << std::endl;
}
}
C++ 异常处理