<new> 运算符和枚举

enum align_val_t

enum class align_val_t : size_t {};

operator delete

delete 表达式调用来为单个对象解除分配存储空间的函数。

void operator delete(void* ptr) noexcept;
void operator delete(void *, void*) noexcept;
void operator delete(void* ptr, const std::nothrow_t&) noexcept;

参数

ptr
其值由删除呈现为无效的指针。

备注

第一个函数由 delete 表达式调用,以将 ptr 的值呈现为无效。 该程序可以通过替换 C++ 标准库定义的默认版本的函数签名定义函数。 所需行为接受 ptr 的值,该值为 nullptr 或由对 operator new 的早期调用返回。

ptrnullptr 值的默认行为是不执行任何操作。 ptr 的任何其他值必须为 new 调用先前返回的值,如上所述。 ptr 的非空值的默认行为是回收早期调用分配的存储空间。 未指定在什么条件下部分或全部此类回收的存储由对 operator new 或任一 callocmallocrealloc 的后续调用分配。

第二个函数由对应于 new( std::size_t ) 形式的 new 表达式的 placement delete 表达式调用。 它不执行任何操作。

第三个函数由对应于 new( std::size_t, const std::nothrow_t& ) 形式的 new 表达式的 placement delete 表达式调用。 该程序可以通过替换 C++ 标准库定义的默认版本的函数签名定义函数。 所需行为接受 ptr 的值,该值为 nullptr 或由对 operator new 的早期调用返回。 默认行为是计算 delete( ptr )

示例

有关使用 operator delete 的示例,请参阅 operator new

operator delete[]

delete 表达式调用来解除对象数组的存储空间分配的函数。

void operator delete[](void* ptr) noexcept;
void operator delete[](void *, void*) noexcept;
void operator delete[](void* ptr, const std::nothrow_t&) noexcept;

参数

ptr
其值由删除呈现为无效的指针。

注解

第一个函数由 delete[] 表达式调用,以将 ptr 的值呈现为无效。 该函数为可替换,因为该程序可以通过替换 C++ 标准库定义的默认版本的函数签名定义函数。 所需行为接受 ptr 的值,该值为 nullptr 或由对 operator new[] 的早期调用返回。 ptr 的 NULL 值的默认行为是不执行任何操作。 ptr 的任何其他值必须为调用之前返回的值,如上所述。 ptr 的此类非空值的默认行为是回收早期调用分配的存储空间。 未指定在什么条件下部分或全部此类回收的存储由对 operator new 或任一 callocmallocrealloc 的后续调用分配。

第二个函数由对应于 new[]( std::size_t ) 形式的 new[] 表达式的 placement delete[] 表达式调用。 它不执行任何操作。

第三个函数由对应于 new[]( std::size_t, const std::nothrow_t& ) 形式的 new[] 表达式的 placement delete[] 表达式调用。 该程序可以通过替换 C++ 标准库定义的默认版本的函数签名定义函数。 所需行为接受 ptr 的值,该值为 nullptr 或由对运算符 new[] 的早期调用返回。 默认行为是计算 delete[]( ptr )

示例

请参阅 operator new[],了解有关使用 operator delete[] 的示例。

operator new

由 new 表达式调用来为单个对象分配存储空间的函数。

void* operator new(std::size_t count);
void* operator new(std::size_t count, const std::nothrow_t&) noexcept;
void* operator new(std::size_t count, void* ptr) noexcept;

参数

count
要分配的存储的字节数。

ptr
要返回的指针。

返回值

指向新分配内存的最小字节地址的指针。 或者 ptr(如果使用函数的第三种形式)。

注解

第一个函数由 new 表达式调用,以便分配 count 个字节的存储,适当对齐该存储以表示该大小的任何对象。 此函数是可替换的。 这意味着程序可以通过替换 C++ 标准库定义的默认版本的函数签名定义 alternate 函数。

仅当按照请求分配存储时,所需的行为才是返回非空指针。 每个此类分配都会向不与任何其他已分配的存储连接的存储生成指针。 未指定连续调用分配的存储的顺序和连续性。 未指定存储的初始值。 返回的指针指向已分配的存储的开始(最小字节地址)。 如果 count 为零,则返回的值不与该函数返回的任何其他值相等。

默认行为是执行一个循环。 在此循环中,该函数会首先尝试分配请求的存储。 未指定该尝试是否涉及调用 malloc。 如果分配尝试成功,则该函数将返回已分配存储的指针。 否则,该函数将调用 new_handler 类型的指定函数。 返回被调用的函数时,将重复该循环。 尝试分配请求的存储成功时或未返回被调用的函数时,循环将终止。

new_handler 类型的函数的所需行为是执行以下操作之一:

  • 使更多存储可用于分配,然后返回。

  • 调用 abortexit

  • 引发 bad_alloc 类型的对象。

new_handler 函数的默认行为是引发一个 bad_alloc 类型的对象。 nullptr 值指定默认 new_handler 函数。

未指定通过连续调用 operator new 分配的存储的顺序和连续性,因为那里存储着初始值。

若要释放由第一种形式的 operator new 分配的存储,请调用 operator delete

第二个函数由 placement new 表达式调用,以便分配 count 个字节的存储,适当对齐该存储以表示该大小的任何对象。 此函数是可替换的。 这意味着程序可以通过替换 C++ 标准库定义的默认版本的函数签名定义 alternate 函数。

如果该函数成功,则默认行为是返回 operator new( count )。 否则,它将返回 nullptr

若要释放由第二种形式的 operator new 分配的存储(即如果未返回 nullptr),请调用 operator delete

第三个函数由 new ( ptr ) T 形式的非分配 placement new 表达式调用。 此处,ptr 包含单个对象指针。 这在构造已知地址的对象时很有用。 该函数返回 ptr。 必须在此对象上显式调用析构函数。

如果调用非分配 placement new,请不要调用 delete。 相反,在为对象调用析构函数后,根据需要为提供的内存调用解除分配器。

有关 new 的引发或非引发行为的信息,请参阅 newdelete 运算符

示例

// new_op_new.cpp
// compile with: /EHsc
#include<new>
#include<iostream>

using namespace std;

class MyClass {
    int member{ 0 };
public:
    MyClass() {
        cout << "MyClass at 0x" << this << " constructed.\n";
    };

    ~MyClass() {
        cout << "MyClass at 0x" << this << " destroyed.\n";
    };
};

int main( )
{
    // The first form of new / delete
    MyClass* fPtr1 = new MyClass;
    delete fPtr1;

    // The second form (fail returns nullptr) of new / delete
    MyClass* fPtr2 = new(nothrow) MyClass[2];
    if (fPtr2)
        delete fPtr2;

    // The third form (non-allocating placement) of new / delete
    char x[sizeof(MyClass)]; // x is automatic
    MyClass* fPtr3 = new(&x[0]) MyClass;
    fPtr3->~MyClass(); // Requires explicit destructor call
    // no delete because x is on the stack
}

operator new[]

由 new 表达式调用来为对象数组分配存储空间的分配函数。

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

参数

count
要为数组对象分配的存储的字节数。

ptr
要返回的指针。

返回值

指向新分配内存的最小字节地址的指针。 或者 ptr(使用第三种形式时)。

注解

第一个函数由 new[] 表达式调用,以便分配 count 个字节的存储,适当对齐该存储以表示该大小或更小的任何数组对象。 该程序可以通过替换 C++ 标准库定义的默认版本的函数签名定义函数。 所需行为与 operator new 的行为相同。 默认行为是在成功时返回 operator new( count )。 否则,它会引发 std::bad_alloc 异常(或派生自 std::bad_alloc 的异常)。 若要释放由这种形式的 operator new[] 分配的存储,请调用 operator delete[]

第二个函数由 placement new[] 表达式调用,以便分配 count 个字节的存储,适当对齐该存储以表示该大小的任何数组对象。 该程序可以通过替换 C++ 标准库定义的默认版本的函数签名定义函数。 如果该函数成功,则默认行为是返回 operator new( count )。 否则,它将返回 nullptr。 若要释放由这种形式的 operator new[] 分配的存储,请调用 operator delete[]。 有关 new 的引发或非引发行为的详细信息,请参阅 newdelete 运算符

第三个函数由 new( ptr ) T[ N ] 形式的非分配 placement new[] 表达式调用。 这种形式不分配内存。 它在内存中构造通过 ptr 参数传入的对象。 该函数返回 ptr。 必须为创建的每个对象显式调用析构函数。 你负责为 ptr 提供足够的内存。 不要对 new 表达式返回的值调用 delete[]。 相反,请根据需要在调用析构函数后解除分配 ptr

示例

// new_op_array.cpp
// compile with: /EHsc
#include <new>
#include <iostream>

using namespace std;

class MyClass {
    int member{ 0 };
public:
    MyClass() {
        cout << "MyClass at 0x" << this << " constructed.\n";
    };

    ~MyClass() {
        cout << "MyClass at 0x" << this << " destroyed.\n";
    };
};

int main() {
    // The first form of array new / delete
    MyClass* fPtr1 = new MyClass[2];
    delete[] fPtr1;

    // The second form (fail returns nullptr) of array new / delete
    MyClass* fPtr2 = new(nothrow) MyClass[2];
    if (fPtr2)
        delete[] fPtr2;

    // The third form (non-allocating placement) of array new / delete
    char x[2 * sizeof(MyClass) + sizeof(int)]; // x is automatic

    MyClass* fPtr3 = new(&x[0]) MyClass[2];
    fPtr3[1].~MyClass(); // Requires explicit destructor calls
    fPtr3[0].~MyClass(); // Recommended in reverse construction order
    // Don't delete[] fPtr3 here.
    // delete[] &x[0] not required because x is on the stack
}