• C++ 异常机制(下)


    八、C++标准异常类

    C++标准库异常类继承层次中的根类为exception,其定义在exception头文件中,它是C++标准库所有函数抛出异常的基类,exception的接口定义如下:

    namespace std {
    
         class exception {
    
         public:
    
              exception() throw();  //不抛出任何异常
    
              exception(const exception& e) throw();
    
              exception& operator= (const exception& e) throw();
    
              virtual ~exception() throw)();
    
              virtual const char* what() const throw(); //返回异常的描述信息
    
         };
    
    }
    

    先来看一下 exception 类的直接派生类:

    异常名称 说 明
    logic_error 逻辑错误。
    runtime_error 运行时错误。
    bad_alloc 使用 new 或 new[ ] 分配内存失败时抛出的异常。
    bad_typeid 使用 typeid 操作一个 NULL 指针,而且该指针是带有虚函数的类,这时抛出 bad_typeid 异常。
    bad_cast 使用 dynamic_cast 转换失败时抛出的异常。
    ios_base::failure io 过程中出现的异常。
    bad_exception 这是个特殊的异常,如果函数的异常列表里声明了 bad_exception 异常,当函数内部抛出了异常列表中没有的异常时,如果调用的 unexpected() 函数中抛出了异常,不论什么类型,都会被替换为 bad_exception 类型。

    logic_error 的派生类:

    异常名称 说 明
    length_error 试图生成一个超出该类型最大长度的对象时抛出该异常,例如 vector 的 resize 操作。
    domain_error 参数的值域错误,主要用在数学函数中,例如使用一个负值调用只能操作非负数的函数。
    out_of_range 超出有效范围。
    invalid_argument 参数不合适。在标准库中,当利用string对象构造 bitset 时,而 string 中的字符不是 0 或1 的时候,抛出该异常。

    runtime_error 的派生类:

    异常名称 说 明
    range_error 计算结果超出了有意义的值域范围。
    overflow_error 算术计算上溢。
    underflow_error 算术计算下溢。

    九、编写自己的异常类

    原则:建议继承标准异常类,并重载父类的what函数和析构函数

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    #include<stdexcept>
    using namespace std;
    
    class Person {
    public:
    	Person() {
    		mAge = 0;
    	}
    	void setAge(int age) {
    		if (age < 0 || age > 100) {
    			throw out_of_range("年龄应该在0-100之间!");
    		}
    		this->mAge = age;
    	}
    public:
    	int mAge;
    };
    //test01()使用标准库的异常类,下面的exception可以换为out_of_range
    void test01() {
    	Person p;
    	try {
    		p.setAge(1000);
    	}
    	catch (exception e) {
    		cout << e.what() << endl;
    	}
    }
    
    //自己写个异常类,重载父类的what函数和析构函数
    class MyOutOfRange : public exception {
    public:
    	MyOutOfRange(const char* error) {
    		pError = new char[strlen(error) + 1];
    		strcpy(pError, error);
    	}
    	~MyOutOfRange() {
    		if (pError != NULL) {
    			delete[] pError;
    		}
    	}
    	virtual const char* what() const {
    		return pError;
    	};
    public:
    	char* pError;
    };
    
    void fun02() {
    	throw MyOutOfRange("我自己的out_of_range!");
    }
    
    void test02() {
    	try {
    		fun02();
    	}
    	catch (exception& e) {
    		cout << e.what() << endl;
    	}
    }
    
    int main(void)
    {
    	test01();//结果:年龄应该在0-100之间!
    	//test02();//结果:我自己的out_of_range!
    	return 0;
    }
    

    十、继承在异常中的应用

    异常尽量抛个类对象(基类),不要再用 -1 或 char* 。

    #define _CRT_SECURE_NO_WARNINGS
    #include <iostream>
    using namespace std;
    
    //异常基类
    class BaseMyException {
    public:
    	virtual void  what() = 0;
    	virtual ~BaseMyException() {}
    };
    
    class TargetSpaceNullException : public BaseMyException {
    public:
    	virtual void  what() {
    		cout << "目标空间空!" << endl;
    	}
    	~TargetSpaceNullException() {}
    };
    
    class SourceSpaceNullException : public BaseMyException {
    public:
    	virtual void  what() {
    		cout << "源空间为空!" << endl;
    	}
    	~SourceSpaceNullException() {}
    };
    void copy_str(char* taget, char* source) {
    
    	if (taget == NULL) {
    		throw TargetSpaceNullException();
    	}
    	if (source == NULL) {
    		throw SourceSpaceNullException();
    	}
    
    	//int len = strlen(source) + 1;
    	while (*source != '') {
    		*taget = *source;
    		taget++;
    		source++;
    	}
    }
    int main(void) {
    
    	const char* source = "abcdefg";
    	char buf[1024] = { 0 };
    	try {
    		copy_str(buf, NULL);
    	}
    	catch (BaseMyException& ex) {
    		ex.what();
    	}
    
    	cout << buf << endl;
    	return 0;
    }
    //结果:源空间为空!
    
  • 相关阅读:
    Linux 详细命令操作大全二
    Liunx 环境安装配置Jupyter
    Linux 详细命令操作大全一
    Mysql int(10)和int(11)区别
    Python 面向对象编程
    Oracle数据库工具设置时间显示格式
    vue安装时报错:npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
    Oracle对当前时间的处理
    Oracle合并不同条件下统计出的总数
    记录一下vue-cli3搭建项目后遇到axios请求跨域的问题
  • 原文地址:https://www.cnblogs.com/gqw-myblogs/p/14286832.html
Copyright © 2020-2023  润新知