【问题标题】:Writing overload function for new operator为 new 运算符编写重载函数
【发布时间】:2011-11-17 22:54:03
【问题描述】:

我写了一个简单的函数如下:

void *operator new(size_t size) throw(std::bad_alloc)
{
    void *p;
    p =  malloc(size);
    if(!p)
       throw bad_alloc();
    return p;
}

我还能做些什么来改善这一点? malloc 会比 new 更有效吗?如果我想写new[] 是否只需要更改函数签名?

【问题讨论】:

  • 你为什么还要覆盖operator new?这是一个非常专用的工具,如果您有这些基本问题,那么它不适合您。
  • @user974191 - 完全正确 - 你重载 new 有什么意义?你想达到什么目的?
  • @CatPlusPlus:请赐教特殊用途。所以我可以停止使用它。我不知道我为什么要这样做。
  • @user974191:你弄错了。 ::operator new() 始终按照malloc() 实现。也许您对::operator new() 和C++ new 表达式 之间的区别感到困惑?
  • 对我来说,您似乎正在尝试“创建”新运算符,就像它根本没有在 C++ 中定义一样。以防万一,您无需重载即可使用它。

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


【解决方案1】:

此代码将按原样运行,但是如果您这样做,您几乎需要编写一个匹配的::operator delete 来使用它:

void operator delete(void *block) throw() {
    ::free(block);
}

就个人而言,我可能会将您的代码修改为更像:

void *operator new(size_t size) throw(std::bad_alloc)
{
    void *p =  malloc(size);
    if(!p)
       throw bad_alloc();
    return p;
}

我更喜欢初始化我所能做的一切,而不是创建一个未初始化的变量,然后再为其赋值。在这种情况下,差异很小,但我认为这是一个值得培养的习惯。

就比operator new 的默认实现更有效而言,我认为很可能不会,它不会更有效,而且可能效果更差。您所提供的基本上是在 C++ 诞生之初实现了多少标准库,但从那时起,许多(大多数?)在实现 ::operator new 方面做了更多工作,以更接近于动态分配内存的趋势在 C++ 中使用(其中malloc 主要面向它在 C 中的使用方式,通常至少有一点不同)。

new[] 而言,是的,这只是函数签名的更改。尽管用于单次分配和多次分配,operator new 和 operator new[]` 的要求是相同的。

【讨论】:

    【解决方案2】:

    如果您替换全局 operator new,您还应该替换 nothrow 变体。当然,全局运算符delete(包括普通和nothrow 变体,因为如果对象的构造函数抛出异常,则operator deletenothrow 变体会为nothrow operator new 调用)。

    我猜在大多数实现中,内置的operator new 看起来或多或少与您的替代品完全一样。无论如何,总的来说,我不希望你能击败 operator new 的内部实现。

    【讨论】:

    • 除了nothrow 版本之外,您通常还需要重载数组版本(operator new[]operator delete[])。
    【解决方案3】:

    operator new 负责分配对象的底层内存。一些应用程序使用除malloc 之外的其他分配方案来分配内存。一个示例是池分配:应用程序向操作系统请求大量内存,并自行管理该内存的方式。这可以保护系统调用的开销、防止碎片或为操作系统通常不会的内存分配提供时间保证。

    如果您不知道这是否可以提高您的程序的性能,那对您来说可能并不重要。

    【讨论】:

      猜你喜欢
      • 2011-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多