理论部分:
使用异常处理,程序中独立开发的各部分能够就程序执行期间出现的问题相互通信,并处理这些问题。程序的一个部分能够检测出本部分无法解决的问题,这个问题部分可以将问题传递给准备处理问题的其他部分。
通过异常处理我们能够将问题的检测和问题的解决分离,这样程序的问题检测部分可以不必了解如何处理问题。C++的异常处理中,需要由问题检测部分抛出一个对象给处理代码,通过这个对象的类型和内容,两部分能够就出现了什么错误进行通信。
直接举例吧,头文件定义了BOOK类,数据成员有编号m_isbn和价格m_price;一个Test类,测试用;一个异常处理类Error,用来处理BOOK抛出的异常,还定义了三种全局的异常类型。
#include<iostream>
#include <string>
using namespace std;
enum TYPE
{
REASON1,
REASON2,
REASON3,
};
class BOOK
{
public:
BOOK(const string& isbn, double price):m_isbn(isbn),m_price(price)
{
cout<<"create book object:"<<m_isbn<<","<<m_price<<endl;
}
~BOOK()
{
cout<<"destroy book object:"<<m_isbn<<endl;
}
BOOK& operator+=(const BOOK& other);
double GetPrice()
{
return m_price;
}
private:
string m_isbn;
double m_price;
};
class Test
{
public:
Test()
{
cout<<"create local object"<<endl;
}
~Test()
{
cout<<"destroy local object"<<endl;
}
};
class Error
{
public:
Error(TYPE type, const string& str):m_type(type),m_means(str)
{
cout<<"create Error object"<<endl;
}
~Error()
{
cout<<"destroy Error object"<<endl;
}
void Solution()
{
cout<<"The kind of this error is: "<<m_type<<", means: "<<m_means<<endl;
}
private:
TYPE m_type;
string m_means;
};
BOOK类自增的实现,也可定义成友元函数,不过属于舍近求远了。
#include <string>
#include "Header1.h"
BOOK& BOOK::operator+=(const BOOK& other)
{
if (other.m_isbn != m_isbn)
{
throw Error(REASON2,"isbn is not match!");
}
m_price += other.m_price;
}
下面是测试代码,主要测试下当两本书的isbn编号不同时,在自增时会不会抛出异常,以及抛出异常的过程中局部对象test什么时候析构。
#include<iostream>
#include "Header1.h"
using namespace std;
void main()
{
BOOK book1("12345", 36.8); //构造BOOK1对象
BOOK book2("12348", 54.9); //构造BOOK2对象
try //下面3行代码预计会抛出异常,因此用Try...Catch...结构处理
{
Test test; //定义局部对象,仅作测试用,看发生异常时什么时候析构
book1 += book2; //只有当两个BOOK对象的isbn编号相等时才不会抛出异常
//若抛出异常,此行代码不会执行,直接跳转到Catch部分
cout<<"The sum is: "<<book1.GetPrice()<<endl;
}
catch (Error& e)
{
//异常处理
e.Solution();
}
system("pause");
}
注意此时两本BOOK对象的isbn编号不相等,看看编译情况
可以发现执行到自增函数式程序抛出了异常,局部对象test也马上被析构了,因此不要抛出局部对象指针或引用也是基于这个原因。
然后将两个BOOK对象的isbn编号改成相等,看看编译情况
可以发现两个BOOK对象可以相加了。