关于使用 C++ 'new' 语法

about using the C++ 'new' syntax

本文关键字:语法 new 于使用 C++      更新时间:2023-10-16

我正在分析向量类。然后,我可以找到这个sytax

(第一个新语法)

void construct(pointer __p, const _Ty& _Val)
    {new ((void *)__p) _Ty(_Val)};
template<typename _Up, typename ... _Args>
    void construct(_Up* __p, _Args&&... __args)
    {new ((void *)__p) _Ty(_STD forward<_Args>(__args)...)};

我能理解这不等于

     __p = new _Ty(_Val);

那么这两个语句之间的区别是什么?我应该如何解释第一个新语法?(在VisualStudio2013中)

它被称为放置新。它不是像正则新表达式那样为对象分配内存,而是在指针指向的内存中构造对象

向量这样做是为了将内存分配与对象构造分开;调用reserve可以为许多元素分配足够的内存,但在向量增长到该内存之前将其留空。

如果你创建这样一个对象,那么它必须通过显式调用其析构函数来销毁:

__p->~_Ty();

这两种说法有什么区别

代码结构:

new (<address>) <typename>{ <arguments> };

称为"新放置"。与默认的new(即没有地址的情况下相同)相反,此调用根本不分配内存,而是假设<address>是已经分配的内存(足够大),并简单地在提供的地址处构造对象。

这并不是new运算符的唯一特殊情况。您还可以将分配器或一些其他(随机)上下文信息传递给new。

为了让new支持这一点(将其他信息传递给操作员),您必须定义一个自定义的operator new实现,该实现接收作为参数的额外信息。要详细了解如何执行此操作,请在线查看(搜索"custom operator new"、"placement new"answers"define custom operator new")请注意,实现自定义新运算符对于正确实现有一些陷阱。这就是为什么如果你计划定义它,你应该阅读更多关于它的信息。

标准库,默认实现new、placement new和(我认为)一个支持std::分配器实例的new。

  __p = new _Ty(_Val);

意味着分配一个内存块(通过malloc),在该空间中构造一个_Ty对象(使用_Val)。存储allocate&__p中的构造块。

 new ((void *)__p) _Ty(_Val)

意味着内存已经分配到地址__p,在该空间中构造一个_Ty对象(使用_Val)