operator new []定义细分

时间:2012-04-06 23:00:39

标签: c++ operator-overloading

我很难消化这种语法:

void* operator new[](std::size_t, const std::nothrow_t&) throw();

虽然仍然可以理解:

void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();

问题:

  1. 我认为new和下标[]是不同的运算符。如何在一个定义中组合两个运算符来重载?

  2. 同样是nowthrow。以下调用对我没有意义(关于函数的签名)。

     int * p2 = new (nothrow) int;
    
  3. 如果有人可以参考bjarne stroustrup的书中的相关主题,那将是很好的,但不是一个很难的要求。

    更新:请尝试回答这两个问题:)

3 个答案:

答案 0 :(得分:3)

new []和[]是两个完全不同的运算符。

new []是数组的分配运算符,[]是数组的下标访问运算符。

new []是它自己的运算符,它不仅仅是'new'分配器与'[]'下标运算符结合。

答案 1 :(得分:2)

前两个是全球新运营商的签名。对于(小)值,operator new用于为x = new T;等新表达式分配空间,而operator new[]用于为x = new T[count];等新表达式分配空间。值得的“小”是一个相当简单的原因:你永远不应该使用new T[count],所以它的工作方式几乎纯粹是历史的好奇心。

如果您愿意,可以重载::operator new和/或::operator new[]以提供自己的堆分配。就基本要求而言,两者之间没有区别 - 它们都只是分配并返回指向所请求内存量的指针。

nothrow而言,传递给operator new的大小始终由编译器根据对象的大小计算,如果是数组,则为新给出的计数。因此,您在新表达式中指定的参数将变为传递给operator new的第二个参数。

要强调一点,我上面可能没有明确说明:operator new(和operator new[])被使用,但与新表达式分开(当你说出某些内容时,你的代码中有什么比如x = new T;)。 operator newoperator new[]非常类似于malloc - 它们只是分配“原始”内存。新表达式 1 使用其中一个来分配原始内存,然后调用构造函数在该内存中分配一个对象(或new T[count];的情况下不止一个)。这两者显然是相关的,但同样显然不是真的相同。

另一个小问题:也可以使用operator new(或operator new[]作为类成员。这允许您为该类分配与使用全局堆的其他内存不同的内存。对于您希望大量分配的小对象,这往往是最常见的。对于这些,全局堆通常会有很多您希望避免的开销。

最后,当/如果要分配原始内存时,您也可以直接调用operator new,如void *a = ::operator new(1234);中所示。关于唯一这个常见的地方是你决定自己实现某种集合类(例如,如果你想要一个循环缓冲区)。

答案 2 :(得分:1)

newnew[]是两个独立的运算符,与'[]'运算符并不真正相关。 最好看出delete pdelete[] p之间的区别;你要删除p指向的单个实例,还是整个实例数组?

同样,new[]是一种分配整个对象数组的方法,所有这些都在同一个内存块中。