c++ std::exception,std::logic_error 异常的使用方法

c++ std::logic_error 异常的使用方法

*** 简单的用法就是如下所示. 抛出一个logic_error()异常,接住,展示.
$ cat main.cpp
#include <iostream>
#include <stdexcept>
using namespace std;
int main()
{
    try
    {
//        logic_error e("test this");
        logic_error e(string("test this ")+"and that"); //显示了字符串类可以直接用+来连接
        throw e; //exception 用法, 如此构造和抛出异常
    }
    catch(exception &ex)    // exception 的用法,如此接受异常
    {
        printf("catch %s\n",ex.what()); //exception 用法,如此访问异常
    }
    return 0;
}

不爽的地方是ctags认不准这种结构了, 在vim中查看很不方便.
在gdb 中也不让查看. 非常不爽!
(gdb) p e
  $1 = <incomplete type>
(gdb) ptype e
  type = class std::logic_error {
      <incomplete type>
  }
 
*** 那这个logic_error 到底是啥呢?
 有时候,c++ 的封装确实不好说是好是坏!
logic_error 是一个exception 的继承类,
在/usr/include/c++/9/stdexcept 文件中定义.
通过qtcreator 找到, 有时IDE 确实在找定义方面更准更强!
// 下面内容有简化
 class logic_error : public exception
  {
    char * _M_msg; //保存信息

  public:
    logic_error(const string& __arg) _GLIBCXX_TXN_SAFE;
    logic_error(const char*) _GLIBCXX_TXN_SAFE;
    logic_error(logic_error&&) noexcept;
    logic_error& operator=(logic_error&&) noexcept;
    logic_error(const logic_error&) = default;
    logic_error& operator=(const logic_error&) = default;
    virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;

    /** Returns a C-style character string describing the general cause of
     *  the current error (the same string passed to the ctor).  */
    virtual const char*
    what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
  };

  可以看出它主要是一些构造函数 和 what() 函数, 无它了, 再看一下exception 类

 class exception
  {
  public:
    exception() _GLIBCXX_NOTHROW { }
    virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
    exception(const exception&) = default;
    exception& operator=(const exception&) = default;
    exception(exception&&) = default;
    exception& operator=(exception&&) = default;

    /** Returns a C-style character string describing the general cause
     *  of the current error.  */
    virtual const char*
    what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
  };

  看来exception 就是一个接口类,logic_error是其一个实现类了.
  会像示例那样使用就可以了.

再给一个具体的使用实例,加深对std::exception ,std::logic_error使用的理解。

#include <iostream> // std::cout std::endl
#include <exception> // std::domain_error, logic_error
#include <cmath> // std::sqrt

double mysqrt(double value)
{
	if (value < 0)
	{
		//        throw std::exception("需要开平方的参数不能是负数");  // exception 不支持字符串参数
		throw std::logic_error("需要开平方的参数不能是负数");
//		throw std::domain_error("需要开平方的参数不能是负数"); // 也可以用domain_error,与logic_error 是2种实现,你也可以书写自己的exception 类,继承自std::exception
	}
	return sqrt(value);
}

int main(void)
{
	try
	{
		std::cout << mysqrt(100) << std::endl;
		std::cout << mysqrt(-100) << std::endl;
		return 0;
	}
	catch (const std::exception &e)
	{
		std::cout << e.what() << std::endl;
	}
	return 0;
}

如果对std::logic_error 还有疑惑的地方,我这里实现一个自己的exception, 它的功能等同于std::logic_error, 并且还给出了测试程序,一并在代码段中给出.

$ cat myexception.h
#ifndef _MY_EXCEPTION_H
#define _MY_EXCEPTION_H
#include <string>
#include <exception>
class MyException : public std::exception 
{ //定义MyException 类
	public:
		MyException(const std::string &msg): _msg(msg){}
		~MyException() throw() {}
		const char *what() const throw() { return _msg.c_str(); }
	private:
		std::string _msg;
};
#endif

hjj@hjj-7090:~/test/myexception$ cat main.cpp 
#include <iostream>
#include "myexception.h"
using namespace std;
int main(void)
{
	try
	{
		throw MyException("an error ocurred!");
		printf("this line won't executed!\n");
	}
	catch(exception &e)
	{
		cout<<"catched "<<e.what()<<endl;
	}
}

执行结果:

$ ./myexception
catched an error ocurred!

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值