操作员新[]定义分解

operator new[] definition breakdown

本文关键字:定义 分解 操作员      更新时间:2023-10-16

我很难消化这个语法:

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. 还有CCD_ 3。下面的调用对我来说没有意义(关于函数的签名)。

     int * p2 = new (nothrow) int;
    

如果有人能参考比约恩·斯特鲁斯特鲁普的书中的相关主题,那就太好了,尽管这不是一个硬性要求。

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

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

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

new[]是它自己的运算符,它不是简单的"new"分配器与"[]"下标运算符组合。

前两个是全局new运算符的签名。不管值多少钱,operator new被用来为像x = new T;这样的新表达式分配空间,而operator new[]被用来为x = new T[count];这样的新表达分配空间。它的"小"价值有一个相当简单的原因:你永远不应该使用new T[count],所以它的工作原理几乎完全是历史的好奇心。

如果需要的话,可以重载::operator new和/或::operator new[]来提供自己的堆分配。就基本需求而言,这两者之间没有什么区别——它们都只是分配并返回一个指向请求内存量的指针。

nothrow而言,传递给operator new的大小总是由编译器根据对象的大小来计算的,在数组为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);中所示。唯一常见的地方是,如果您决定自己实现某种集合类(例如,如果您想要一个循环缓冲区)。

newnew[]是两个独立的运算符,与"[]"运算符没有真正的关系。这在CCD_ 27和CCD_;您是删除p指向的单个实例,还是删除整个实例数组?

同样,nowthrow0是一种分配整个对象阵列的方式,所有对象都在同一个内存块中。