New (C++)

new是C++程序设计语言中的一种语言结构，用于动态分配内存、并用构造函数初始化分配的内存。 
new的使用称为“new运算符表达式”，其内部实现分为两步：
每个new获取的对象，必须用delete析构并释放内存，以免内存泄漏。 
new运算符表达式是C++的一种语言结构，不可重载。但用户可重载operator new()函数。
new运算符表达式语法.
普通的new运算符表达式.
new的语法是:
其中codice_2是已经定义的类型为codice_3的指针变量。 
通过codice_4初始化对象，使用下述语法：
其中codice_5是传递给构造函数的实参表或初值。
动态生成对象数组的new运算符表达式.
codice_4也可创建一个对象数组，称之为“array forms new”：
C++98标准规定，codice_4创建的对象数组不能被显式初始化， 数组所有元素被缺省初始化。如果数组基类型没有缺省初始化，则编译报错。但C++11已经允许显式初始化，例如：
如此生成的对象数组，在释放时必须调用codice_8表达式。例如<syntaxhighlight lang="cpp"> delete [] p_int ;</syntaxhighlight>
带位置的new运算符表达式.
带位置的new （placement new）的语法是：
其中，expression-list将作为operator new()函数的实参列表的结尾部分。这种形式的new运算符表达式首先调用operator new(size_t,OtherTypeList)函数来获取内存；然后对该对象执行构造函数。这里的OtherTypeList作为形参列表要和new表达式中第一个括号里的实参列表expression-list的类型兼容（即形参实参能够匹配）。
带位置的new运算符，语义上包括四种使用情形，其中前两种已经在标准头文件<new>中实现了：
狭义上的带位置的new是指第一种情形。使用这种placement new，原因之一是用户的程序不能在一块内存上自行调用其构造函数（即用户的程序不能显式调用构造函数），必须由编译系统生成的代码调用构造函数。原因之二是可能需要把对象放在特定硬件的内存地址上，或者放在多处理器内核的共享的内存地址上。
释放这种对象时，不能调用placement delete，应直接调用析构函数，如：codice_9然后再自行释放内存。
举例：
<syntaxhighlight lang="cpp">
using namespace std;
int main(int argc, char* argv[])
</syntaxhighlight>
保证不抛出异常的new运算符表达式.
在分配内存失败时，new运算符的标准行为是抛出codice_1异常。也可以让new运算符在分配内存失败时不抛出异常而是返回空指针。
或
其中codice_11是codice_12的一个实例
自行定制参数的new运算符表达式.
new运算符的参数可以是任意合法类型的列表。由C++的重载机制来决定调用那个operator new。
或
带位置的delete运算符表达式.
C++ 不能使用带位置的 delete 运算符表达式直接析构一个对象但不释放其内存。因此，对于用广义的带位置new表达式构建的对象，析构释放时有两种办法：
第一种办法是直接写一个函数，完成析构对象、释放内存的操作：
<syntaxhighlight lang="cpp">
</syntaxhighlight>
如此使用：
<syntaxhighlight lang="cpp">
A arena ;
T * p = new (arena) T ;
destroy(p, arena) ;
</syntaxhighlight>
第二种办法是分两步显式调用析构函数与带位置的operator delete函数：
<syntaxhighlight lang="cpp">
A arena ;
T * p = new (arena) T ;
p->~T() ; // First invoke the destructor explicitly.
operator delete(p, arena) ; // Then call the deallocator function indirectly via operator delete(void *, A &) .
</syntaxhighlight>
带位置的operator delete()函数，可以被带位置的new算符表达式自动调用。这是在对象的构造函数抛出异常的时候，用来释放掉带位置的operator new函数获取的内存。以避免内存泄露。
例如：
char buf;
struct A {} ;
struct E {} ;
class T {
public:
void * operator new ( std::size_t, const A & )
void operator delete ( void *, const A & )
int main ()
</syntaxhighlight>
operator new()的函数重载.
使用new动态生成一个对象，实际上是调用了new运算符表达式。该运算符首先调用了operator new函数动态分配内存，然后调用类型的构造函数初始化这块内存。new运算符是不能被重载的，但是下述各种operator new()函数既可以作为全局函数重载，也可以作为类成员函数或作用域内的函数重载，即由编程者指定如何获取内存。
普通的operator new(size_t size)函数.
new运算符调用operator new函数动态分配内存。首先查找类内是否有operator new函数可供使用（即依赖于实参的名字查找）。operator new函数的参数是一个size_t类型，指明了需要分配内存的规模。operator new函数可以被每个C++类作为成员函数重载。也可以作为全局函数重载：
<syntaxhighlight lang="cpp">
void * operator new (std::size_t) throw(std::bad_alloc);
void operator delete(void*) throw();
</syntaxhighlight>
内存需要回收的话,调用对应的operator delete()函数。
例如，在new运算符表达式的第二步，调用构造函数初始化内存时如果抛出异常，异常处理机制在栈展开（stack unwinding）时，要回收在new运算符表达式的第一步已经动态分配到的内存，这时就会自动调用对应operator delete()函数。
数组形式的operator new[](size_t size)函数.
new Type[]运算符（array forms new），用来动态创建一个对象数组。这需要调用数组基类型内部定义的void* operator new[ ](size_t)函数来分配内存。如果数组基类型没有定义该函数，则调用全局的void* operator new[ ](size_t)函数来分配内存。
在<new>中声明了void* operator new[ ](size_t)全局函数：
<syntaxhighlight lang="cpp">
void * operator new[] (std::size_t) throw(std::bad_alloc);
void operator delete[](void*) throw();
</syntaxhighlight>
void* operator new(size_t,void*).
operator new(size_t,void*)函数用于带位置的new运算符调用。C++标准库已经提供了operator new(size_t,void*)函数的实现，包含<new>头文件即可。这个实现只是简单的把参数的指定的地址返回，带位置的new运算符就会在该地址上调用构造函数来初始化对象：
<syntaxhighlight lang="cpp">
// Default placement versions of operator new.
// Default placement versions of operator delete.
</syntaxhighlight>
禁止重定义这4个函数。因为都已经作为<new>的内联函数了。在使用时，实际上不需要codice_13
对应的placement delete函数，只应在placement new运算符表达式在第二步调用构造函数抛出异常时被异常处理机制的栈展开操作自动调用。 
保证不抛出异常的operator new函数.
C++标准库的<new>中还提供了一个nothrow的实现，用户可写自己的函数替代：
<syntaxhighlight lang="cpp">
void* operator new(std::size_t, const std::nothrow_t&) throw();
void* operator new[](std::size_t, const std::nothrow_t&) throw();
void operator delete(void*, const std::nothrow_t&) throw();
void operator delete[](void*, const std::nothrow_t&) throw();
</syntaxhighlight>
自行定制参数的operator new函数.
这种函数被自行定制参数的new算符调用。需要由用户自行定义，以确定分配内存时的行为：
例如：
<syntaxhighlight lang="cpp">
char data[sizeof(int)];
inline void* operator new(size_t ,int n)
void foo(){ 
</syntaxhighlight>