wbczyh 2020-05-03
尽管C++预定义了很多标准异常类,但可能还是无法满足我们的需求,这时候我们可以自定义异常类来描述异常。当然,如果使用C++定义的异常类就可以满足,那么尽量使用C++定义的异常类,而避免创建自己的异常类。
异常类同一般的C++类没什么区别,除了它派生自exception类或者其派生类(如runtime_error等),这样我们就可以使用exception类中的一些公共特性如what函数等。
如一个圆的半径不应该小于或者等于0,所以我们可以定义一个CircleException类,继承自logic_error类。
首先是CircleException.h文件,为了方便,我们直接实现了类而没有进行分离
#ifndef CIRCLEEXCEPTION_H #define CIRCLEEXCEPTION_H #include <stdexcept> using namespace std; class CircleException: public logic_error { public: CircleException(double radius): logic_error("Invaild circle") { this->radius = radius; } double getRadius() const { return radius; } private: double radius; }; #endif // CIRCLEEXCEPTION_H
在Circle.h文件中导入CircleException.h文件
#ifndef CIRCLE_H #define CIRCLE_H #include "GeometricObject.h" #include "CircleException.h" #include <string> using namespace std; class Circle: public GeometricObject { public: //无参构造函数 Circle(); //有参构造函数,半径为radius,颜色为color Circle(const double radius, const string& color); //其他的属性和操作无需再写一遍,因为继承了GeometricObject类 //如果有需要可以再添加属性和方法等如下面的radius //获取圆的半径 double getRadius() const; string getColor() const; double getArea() const; string toString() const; private: //圆的半径 double radius; }; #endif // CIRCLE_H
接下来修改Circle.cpp文件,在有参构造函数中抛出异常CircleException
#include "Circle.h" using namespace std; Circle::Circle(){ this->radius = 1; this->color = "white"; } Circle::Circle(const double radius, const string& color) { if(radius <= 0) { throw CircleException(radius); } this->radius = radius; this->color = color; } double Circle::getArea() const { return radius*radius*3.14; } double Circle::getRadius() const { return radius; } string Circle::getColor() const { return color; } string Circle::toString() const { return "Circle Object"; }
接下来main函数进行测试
#include <iostream> #include "Circle.h" using namespace std; int main(){ try{ Circle circle(-1, "white"); }catch(CircleException& e){ cout << e.what() << endl; cout << "半径为" << e.getRadius() << endl; } return 0; }
运行结果:
我们不但处理了异常,并且传递了更多的信息如圆的非法半径,这就是使用异常类的好处。