C++学习——C++异常

异常处理

异常处理就是处理程序中的错误。所谓错误是指在程序运行的过程中发生一些异常事件(如:除0溢出,数组下标越界,所要读取的文件不存在,空指针,内存不足等等)

try 试图执行{}中的内容,在可能出现异常的地方,抛出异常throw,try下面catch捕获异常。如果不想处理异常,继续向上抛出 throw,如果没有任何处理异常的地方,那么成员调用terminate函数,程序中断

int myDevice(int a, int b)
{
	if (b == 0)
	{
		//如果b异常 抛出异常
		//return -1;
        //throw 3.14;  //抛出double类型的异常,异常必须处理catch(double)
		throw -1;
	}
	return a / b;
}

void test01()
{
	int a = 10;
	int b = -10;

	int ret = myDevice(a, b);  //早期如果返回-1,无法区分到底是结果还是异常

	//C++中异常处理
	try
	{
		myDevice(a, b);
	}
	catch (int)    //捕获异常
	{
		cout << "int类型异常捕获" << endl;
	}
    catch(...)
    {
        cout << "其他类型异常捕获" << endl;
    }
}

自定义异常进行捕获

//自定义异常类
class myException
{
public:
	void printError()
	{
		cout << "自定义的异常" << endl;
	}
};

int myDevice(int a, int b)
{
	if (b == 0)
	{
		throw myException();  //匿名对象
	}
	return a / b;
}

void test01()
{
	int a = 10;
	int b = 0;

	try
	{
		myDevice(a, b);
	}
	catch (myException e)
	{
		e.printError();
	}
}

栈解旋

从try开始  到throw 抛出异常之前 所有栈上的对象 都会释放 这个过程称为栈解旋
构造和析构顺序是相反的

//自定义异常类
class myException
{
public:
	void printError()
	{
		cout << "自定义的异常" << endl;
	}
};

class Person
{
public:
	Person()
	{
		cout << "默认构造" << endl;
	}

	~Person()
	{
		cout << "析构" << endl;
	}
};

int myDevide(int a, int b)
{
	if (b == 0)
	{
		//栈解旋
		//从try开始  到throw 抛出异常之前 所有栈上的对象 都会释放 这个过程称为栈解旋
		//构造和析构顺序是相反的
		Person p1;
		Person p2;

		throw myException(); //抛出异常
	}
	return a / b;
}


void test01()
{
	int a = 10;
	int b = 0;
	try
	{
		myDevide(a, b);
	}
	catch (myException e)
	{
		e.printError();
	}
}

异常接口声明

只想抛出一个特定类型的异常,其他的都不抛出

只能在Qt或Linux下应用

void func() throw(int)  //throw(int)只能抛出int类型异常,throw()不抛出任何类型异常
{
    throw 1;
}

void test01()
{
    try
    {
        func();
    }
    catch(int)
    {
        qDebug << "int类型异常捕获" << endl;
    }
}

异常变量的生命周期

myException e因为调用拷贝构造,会多开销一份数据

myException *e,不new的话会提前释放对象  new自己管理delete

myException &e,容易些,而且 就一份数据

class myException
{
public:
	myException()
	{
		cout << "myException的默认构造" << endl;
	}
	~myException()
	{
		cout << "myException的析构构造" << endl;
	}
	myException(const myException &e)
	{
		cout << "myException的拷贝构造" << endl;
	}
};

void doWork()
{
	throw myException();
}

void test01()
{
	try
	{
		doWork();
	}
	catch (myException &e)   //myException e因为调用拷贝构造,会多开销一份数据
	{
		cout << "捕获异常" << endl;
	}
}

异常的多态使用

利用多态来实现 printError同一个接口调用,抛出不同的错误对象,提示不同的错误

class BaseException
{
public:
	virtual void printError()
	{

	}
};

class NullPointerException :public BaseException
{
public:
	virtual void printError()
	{
		cout << "空指针异常" << endl;
	}
};

class OutofRangeException :public BaseException
{
public:
	virtual void printError()
	{
		cout << "越界异常" << endl;
	}
};

void doWork()
{
	throw NullPointerException();  //调用空指针异常
	//throw OutofRangeException(); //调用越界异常
}

void test01()
{
	try
	{
		doWork();
	}
	catch (BaseException &e)
	{
		e.printError();
	}
}

使用系统标准异常

//系统提供标准异常,要包含头文件
#include <stdexcept>

class Person
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		if (age < 0 || age>0)
		{
			//抛出越界异常
			//throw out_of_range("年龄越界了");

			throw length_error("长度越界");
		}
	}
	string m_Name;
	int m_Age;
};

void test02()
{
	try
	{
		Person p("Tom", 300);
	}
	catch (out_of_range &e)
	{
		cout << e.what() << endl;
	}
	catch (length_error &e)
	{
		cout << e.what() << endl;
	}
}

编写自己的异常类

//编写自己的异常类, 继承系统标准异常类
class MyOutofRangeException :public exception
{
public:
	MyOutofRangeException(string errorInfo)
	{
		this->m_ErrorInfo = errorInfo;
	}

	virtual ~MyOutofRangeException()
	{
		
	}

	virtual char const* what() const
	{
		//string 转char*:.c_str()
		return this->m_ErrorInfo.c_str();
	}
	string m_ErrorInfo;
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值