我很难消化这种语法:
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();
问题:
我认为new
和下标[]
是不同的运算符。如何在一个定义中组合两个运算符来重载?
同样是nowthrow
。以下调用对我没有意义(关于函数的签名)。
int * p2 = new (nothrow) int;
如果有人可以参考bjarne stroustrup的书中的相关主题,那将是很好的,但不是一个很难的要求。
更新:请尝试回答这两个问题:)
答案 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 new
和operator new[]
非常类似于malloc
- 它们只是分配“原始”内存。新表达式 1 使用其中一个来分配原始内存,然后调用构造函数在该内存中分配一个对象(或new T[count];
的情况下不止一个)。这两者显然是相关的,但同样显然不是真的相同。
另一个小问题:也可以使用operator new
(或operator new[]
作为类成员。这允许您为该类分配与使用全局堆的其他内存不同的内存。对于您希望大量分配的小对象,这往往是最常见的。对于这些,全局堆通常会有很多您希望避免的开销。
最后,当/如果要分配原始内存时,您也可以直接调用operator new
,如void *a = ::operator new(1234);
中所示。关于唯一这个常见的地方是你决定自己实现某种集合类(例如,如果你想要一个循环缓冲区)。
答案 2 :(得分:1)
new
和new[]
是两个独立的运算符,与'[]'运算符并不真正相关。
最好看出delete p
和delete[] p
之间的区别;你要删除p
指向的单个实例,还是整个实例数组?
同样,new[]
是一种分配整个对象数组的方法,所有这些都在同一个内存块中。