一个例子演示了C++异常的推荐用法

一个例子演示了C++异常的推荐用法

再读《More Effective C++》异常部分,觉得异常应该这样用:
在throw语句里构造异常;通过引用(reference)捕获异常;禁止自定义异常的拷贝构造函数;

稍啰嗦些的结论如下:

1.总是使用引用(Reference)捕获异常!
2.推荐抛出异常的做法:throw my_exception_class()
3.也可以先定义一个局部异常对象,然后再抛出它: throw my_exception_instance_local
4.在抛出异常的时候不要使用new,不要使用指针捕获异常;
5.也不要使用传值的方式捕获异常,会造成slicing问题。
6.按照上面推荐的做法,我们自定义的异常应该明确禁止拷贝构造函数!
7.使用语句 throw ; 将异常再抛出!

更多内容详见《More Effective C++》条款12和条款13, 条款12解释了如何抛出异常,条款13解释了如何捕获异常!


以下例子演示了正确的做法!  会说话的代码需要你把它跑起来:)

#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;
//异常类
class my_validation_error : public runtime_error
{
public:
    my_validation_error(const stringmsg) : runtime_error(msg
    {
        cout << "my_validation_error construction" << endl;
    }
    virtual ~my_validation_error() 
    {
        cout << "my_validation_error destruction" << endl;
    }
    //拷贝构造函数,推荐的做法是将该函数设为 private !
    my_validation_error(const my_validation_errorother) : runtime_error(other)
    {
        cout << "my_validation_error copy construction" << endl;
    }
public:
    virtual const charwhat() throw()
    {
        return "my_validation_error: ";
    }
};
void SomeFunction()
{
    //do something
    
    if (true//validation error
    {
        throw my_validation_error("validation error in SomeFunction!"); //推荐做法
    }
}
void DoSomething()
{
    try
    {
        SomeFunction();
    }
    catch (exceptionex)
    {
        cerr << ex.what() << endl;
    }
}
void DoSomething2();
int main()
{
    string comment;
    {
        comment = "test case 1: 在throw语句里构造对象并抛出!这是较好的做法,比起下面的做法,效率略好,省略了一次拷贝操作!";
        cout << comment << endl;
        DoSomething();
        cout << endl;
    }
    
    {
        comment = "test case 2: 抛出局部对象, C++规范要求被做为异常抛出的对象必须被复制。";
        cout << comment << endl;
        DoSomething2();
        cout << endl;
    }

    comment = "结论:\n1.总是使用引用(Reference)捕获异常!\n"
        "2.推荐抛出异常的做法:throw my_exception_class()\n"
        "3.也可以先定义一个局部异常对象,然后再抛出它: throw my_exception_instance_local\n"
        "4.在抛出异常的时候不要使用new,不要使用指针捕获异常;\n"
        "5.也不要使用传值的方式捕获异常,会造成slicing问题。\n"
        "6.按照上面推荐的做法,我们自定义的异常应该明确禁止拷贝构造函数!\n"
        "\n更多内容详见《More Effective C++》条款12和条款13。\n"
        ;
    cout << comment << endl;

    return 0;
}
void SomeFunction2()
{
    //do something
    if (true//validation error
    {
        my_validation_error temp("validation error in SomeFunction!");
        throw temp//不用担心,局部变量可以放在throw语句里被抛出,它会被复制!C++规范要求被做为异常抛出的对象必须被复制!
    }
}
void DoSomething2()
{
    try
    {
        SomeFunction2();
    }
    catch (exceptionex)
    {
        cerr << ex.what() << endl;
    }
}

运行结果:






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值