为了账号安全,请及时绑定邮箱和手机立即绑定

如何编写符合ISO C+标准的自定义新操作符和删除操作符?

如何编写符合ISO C+标准的自定义新操作符和删除操作符?

C++
翻过高山走不出你 2019-07-27 12:15:13
如何编写符合ISO C+标准的自定义新操作符和删除操作符?如何编写ISO C+标准一致性自定义new和delete操作员?这是继续重载新的和删除的在非常有启发性的C+FAQ中,操作者超载它的后续行动,为什么要替换默认的新操作符和删除操作符?第1节:编写符合标准的new操作者第1部分:理解编写自定义的要求new操作者第2部分:理解new_handler所需第3部分:理解特定场景需求第2节:编写符合标准的delete操作者实现自定义删除操作符(注:这是指堆栈溢出的C+常见问题..如果您想批评以这种形式提供常见问题的想法,那么在元网站上发布的文章引发了这一切就是这样做的地方。对该问题的回答将在C+聊天室你的答案很可能会被那些想出这个想法的人读懂。)注意:答案是基于从ScottMeyers的更有效的C+和ISO C+标准中学到的。
查看完整描述

3 回答

?
12345678_0001

TA贡献1802条经验 获得超5个赞

第二部分

..续

鉴于.的行为operator new从这个例子看,一个精心设计的new_handler 必执行下列操作之一:

提供更多内存:这可能允许运算符New‘s循环中的下一次内存分配尝试成功。实现这一点的一种方法是在程序启动时分配一个大内存块,然后在第一次调用新处理程序时释放它以便在程序中使用。

安装不同的新处理程序:如果当前的新处理程序无法提供更多可用内存,并且有另一个新处理程序可以使用,则当前的新处理程序可以在其位置安装另一个新处理程序(通过调用set_new_handler)。下次运算符新调用新处理程序函数时,它将得到最近安装的函数。

(这个主题的一个变体是由一个新的处理程序来修改它自己的行为,所以下一次调用它时,它会做一些不同的事情。实现这一目标的一种方法是让新处理程序修改影响新处理程序行为的静态、命名空间特定的或全局数据。)

卸载新的处理程序:这是通过将空指针传递给set_new_handler..没有安装新的处理程序,operator new将引发异常(可转换为)std::bad_alloc当内存分配失败时。

抛出异常可转换到std::bad_alloc..这类例外情况是不会被发现的。operator new,但将传播到发起内存请求的站点。

不返回:打电话abortexit.

实现特定于类的new_handler我们必须提供一个具有它自己的版本的类。set_new_handleroperator new..全班set_new_handler允许客户端为类指定新的处理程序(与标准完全相同)。set_new_handler允许客户端指定全局新处理程序)。全班operator new确保在分配类对象的内存时使用类特定的新处理程序代替全局新处理程序。


现在我们明白了new_handler & set_new_handler更好的是,我们能够修改要求#4适当地作为:

要求4(增强):
我们的operator new应该尝试分配内存不止一次,每次失败后调用新的处理函数。这里的假设是,新的处理函数可能能够做一些事情来释放一些内存。只有当指向新处理函数的指针是null是吗?operator new抛出一个异常。

正如承诺的那样,来自标准的引文:
第3.7.4.1.3节:

未能分配存储的分配函数可以调用当前安装的new_handler(18.4.2.2(如有的话)。[注意:程序提供的分配函数可以获得当前安装的地址。new_handler使用set_new_handler功能(18.4.2.3)]如果使用空异常声明的分配函数-规范(15.4), throw()无法分配存储,它将返回一个空指针。未分配存储的任何其他分配函数只能通过抛出类的异常来指示失败。std::bad_alloc(18.4.2.1)或派生自std::bad_alloc.

带着#4要求,让我们尝试为我们的new operator:

void * operator new(std::size_t size) throw(std::bad_alloc){  
   // custom operator new might take additional params(3.7.3.1.1)

    using namespace std;                 
    if (size == 0)                     // handle 0-byte requests
    {                     
        size = 1;                      // by treating them as
    }                                  // 1-byte requests

    while (true) 
    {
        //attempt to allocate size bytes;

        //if (the allocation was successful)

        //return (a pointer to the memory);

        //allocation was unsuccessful; find out what the current new-handling function is (see below)
        new_handler globalHandler = set_new_handler(0);

        set_new_handler(globalHandler);


        if (globalHandler)             //If new_hander is registered call it
             (*globalHandler)();
        else 
             throw std::bad_alloc();   //No handler is registered throw an exception

    }}

延续2




查看完整回答
反对 回复 2019-07-28
  • 3 回答
  • 0 关注
  • 225 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信