异常
程序在实际运行时,总会有一些因素会导致程序不能正常运行。异常就是提前给出处理这些不正常因素的解决方案的机制。主要是为了程序的稳定性。
C++中的异常
关键字
在C++中主要提供了3个关键字实现异常处理。分别是:
- try:捕捉异常
try块中的代码将会进行异常捕捉。
- catch:处理异常
在catch块中进行对应异常的处理。可以有多个catch块处理不同的异常。异常类可以是任何类型,比如int、long、char*、自定义类。
- throw:抛出异常
抛出异常后,throw下面的语句将不会被执行。此时执行退栈操作。
Java中的异常机制就是使用C++的异常实现的。
异常处理中的退栈和对象析构
在函数调用时,函数中定义的自动变量将在堆栈中存放。结束函数调用时,这些自动变量就会从堆栈中弹出,不再占用堆栈的空间,这个过程也被称为”退栈”。退栈时会调用对象的析构函数并释放对象。
异常使用示例
#include <iostream>
void main(){
try
{
// 在try块中的代码抛出的异常将会被捕捉
throw "异常了"; // throw可以抛出任何类型的异常,比如char*、int、自定义类
// throw下面的代码将不会被执行,此时执行退栈操作。
std::cout << "--------------------" << std::endl;
throw 505;
}
catch (const char* str) //根据类型catch不同的异常,并在catch块中对该异常作处理
{
std::cout << "error msg : " << str << std::endl;
}
catch (int i)
{
std::cout << "error code : "<< i << std::endl;
}
}
自定义异常类
子类异常要放在父类异常的前面,不然子类异常将永远不会被catch到。但可以使用虚函数实现同一个接口处理不同的异常。
// 异常类
class Exception{
protected:
std::string _msg;
public:
Exception(){
}
Exception(std::string &str){
_msg = str;
}
virtual void print(){
std::cout << _msg.c_str() << std::endl;
}
};
// 数组下标访问越界异常
class ArrayIndexOutOfBoundsException:public Exception{
protected:
int _errorIdx;
public:
ArrayIndexOutOfBoundsException(int idx){
_errorIdx = idx;
}
void print(){
std::cout << "ArrayIndexOutOfBoundsException : 尝试访问下标" << _errorIdx << "时发生错误。" << std::endl;
}
};
// 数组
template<class T>
class Array{
private:
int _size = 0;
T *arr = nullptr;
public:
Array(int size){
arr = new T[size];
_size = size;
}
~Array(){
if (arr)
{
delete[] arr;
arr = nullptr;
}
}
T& operator[](int idx){
// 检查下标
if (idx < 0 || idx >= _size)
{
throw ArrayIndexOutOfBoundsException(idx); //数组下标访问越界
}
return arr[idx];
}
};
void main(){
int size = 5;
try{
Array<int> arr(size);
for (int i = 0; i < size; ++i)
arr[i] = i + 1;
// 异常
arr[-1] = 0;
for (int i = 0; i < size; ++i)
{
std::cout << "arr[" << i << "] = " << arr[i] << std::endl;
}
}
// 子类异常要放在父类异常之前
catch (ArrayIndexOutOfBoundsException &e){
e.print();
}
catch (Exception &e){
e.print();
}
}
时间: 2024-10-10 00:26:48