VC的std::exception的问题

我工作的工程里现在代码里有这样的使用方法:

class Exception : public std::exception
{
public:
    Exception(const char * const msg)
        :std::exception(msg)
    {
    }
};
 
void throwFunc()
{
    std::string str("abc");
    throw Exception(str.c_str());
}
void main()
{
    try
    {
        throwFunc();
    }
    catch (const std::exception&e)
    {
        std::cout << e.what();
    }
}

以这种方式使用实际上是没有问题的,但是总感觉有点怪怪的。

问题的核心在于

std::exception(char const* const _Message);

传入的参数是一个原始指针,这种指针并没有规定其指向的对象的生命周期由谁管理,通常是由调用者管理,也就是谁申请谁释放。

第一段代码的用法也是这样,但是上述构造函数有进行复制吗?

explicit exception(char const* const _Message) throw()
    : _Data()
{
    __std_exception_data _InitData = { _Message, true };
    __std_exception_copy(&_InitData, &_Data);
}

看起来 __std_exception_copy函数是复制数据的,但是我没有查到相关文档,只能看实验的结论了。

当然结论是确实复制了, __std_exception_data的另一个成员名是_DoFree,看来就是明确字符串归属问题的。所以这个构造方法是可以保证资源的有效性,也能正确释放。

但是exception还有另外一个构造函数:

exception(char const* const _Message, int) throw()
    : _Data()
{
    _Data._What = _Message;
}

就多了一个匿名的int参数,看起来这个重载形式的意思就是只存储一下指针,并不管理也不关心资源的问题。

当我刚看到这个函数时感觉非常奇怪:这个函数的目的是啥?为了省掉复制这个字符串的时间?都抛异常了还在乎这点时间吗?

但是就在写这个文档时,突然想到复制字符串除了需要时间,还需要空间。如果当前这个异常本身就是bad_alloc,那可能连容纳这个字符串的地方都没有了,复制会失败。所以这个形式还是有意义的。

PS:请思考当内存耗尽时如何正常地处理类似异常、写日志等任务?

PS:C++标准中std::exception只有一个无参构造和复制构造。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值