【问题标题】:Putting restrictions in overloading new and delete限制重载 new 和 delete
【发布时间】:2011-07-03 13:19:59
【问题描述】:

是否可以在重载运算符 new 和 delete 时设置一些限制? 我重载的 new 在不同的文件中链接到我的测试程序。

场景是:

if(condition is satisfied)
   call overloaded new
else
   call the actual new defined in new.h

【问题讨论】:

  • 是重载(即不同的签名,需要使用放置新语法调用)还是替换(即与您要调用的版本相同的签名)。
  • @STATUS_ACCESS_DENIED,我刚刚添加了它...
  • @AProgrammer:placement new 在这里有什么作用?

标签: c++ overloading new-operator delete-operator


【解决方案1】:

始终使用重载的new/delete 并在其实现中检查您的条件。

【讨论】:

  • 条件可以查,但是如果是假的,怎么回到原来的新的呢?我的意思是 new.h 中的新内容?
【解决方案2】:

一旦你替换了默认的::operator new(),你就不能再使用它了——它永远消失了。 See this question.

如果您想获得原始::operator new() 的效果,则必须重新实现它,这并不难。

【讨论】:

    【解决方案3】:

    提供运算符 new 的三种方式。

    • 替换四个非放置默认运算符中的一个或多个新,

    • 为默认运算符 new 提供重载(因此使用附加参数,可以使用放置 new 语法调用这些参数),

    • 提供操作员新的类成员,这些成员将只为该类及其后代调用。

    在后两种情况下,可以使用以下语法调用更广为人知的运算符之一:

    ptr = ::operator new(sz);
    ptr = ::operator new[](sz);
    ptr = ::operator new(sz, std::nothrow);
    ptr = ::operator new[](sz, std::nothrow);
    

    但是如果你替换了它们,你的替换将被调用。 您不能将已替换的默认运算符称为 new(也许您可以通过播放特定于实现的链接器技巧来调用,但这超出了语言的范围)。

    关于operator new的替换:

    • 您应该将两个运算符 new 和相应的两个运算符 delete 一起替换(或者删除运算符之一可以很容易地被意外指针调用)
    • 您应该将两个运算符 new[] 和对应的两个运算符 delete[] 一起替换(同理)
    • 注意新处理程序的可能性,一些库会使用它。

    【讨论】:

      【解决方案4】:

      您可以轻松地在重载的 new 运算符中执行检查。确保实现新操作符的所有风格(正如 AProgrammer 已经指出的那样)。

      调用原来的/默认的new是不可能的,但是自己实现也不难。毕竟 new 只分配内存,仅此而已。因此,您也可以调用 malloc、HeapAlloc 或系统上的任何内存分配例程,而不是调用原始/默认 new。请务必在您的删除实现中调用相应的内存释放方法(free、HeapFree、...)。

      您没有说明您将在执行 new 时检查什么样的条件?如果它是“静态”条件(我的意思是:在您的应用程序执行期间总是给出相同的结果),那么同样的条件也应该添加到您的删除实现中。

      如果条件取决于情况并在运行应用程序时发生变化,您应该预见一种方法,您可以知道在删除函数中使用哪个删除实现。这样做的一个技巧如下:

      在你的新实现中:

      • 分配比请求多 8 个字节(这必须是 8 个字节以保持对齐正确)
      • 在前 8 个字节中填写一个标识,这样您就可以知道您使用了哪个底层内存分配函数
      • 向分配的指针添加 8 个字节并返回这个

      在你的删除实现中:

      • 给你的指针减去 8 个字节
      • 检查在那个地方找到的标识(见新的),看看你应该调用哪种底层删除实现

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-18
        相关资源
        最近更新 更多