为什么非放置的`new`和`delete`内置于语言中而不仅仅是常规函数?

Vit*_*meo 38 c++ new-operator delete-operator

为什么非放置new表达式delete表达式实现为内置语言而不是常规函数?

如果我们有...

  • 一种向OS请求/回馈内存的方法

  • 一种显式调用构造函数的方法(放置new)

  • 一种显式调用析构函数的方法(~T())

...为什么不能放置new,delete只是标准库中的常规功能?例:

template <typename T, typename... Ts>
T* library_new(Ts&&... xs)
{
    auto* ptr = /* request enough memory for `T` from OS */;
    new (ptr) T(std::forward<Ts>(xs)...);
    return ptr;
}

template <typename T>
void library_delete(T* ptr)
{
    ptr->~T();
    /* reclaim memory for `T` from OS */
} 
Run Code Online (Sandbox Code Playgroud)

Cur*_*ous 26

如果用户的目标是在某个内存位置创建一个对象,那么这new似乎是一种自然的方法,因为转发引用,可变参数模板新的位置在那些日子里不是回归.正如@TC模板正确指出的那样,于1990年发布,并于1989年发布新版本.另一方面,Variadic模板仅在C++ 11中成为C++的一部分.

tl; dr 没有办法将一堆参数转发给任意类型的构造函数(正如你现在可以用make函数做的那样).

  • 这是至关重要的最后一段,我认为你应该把它作为第一段."历史事故:在C++的原始版本中,没有办法将`new`写成库函数.一旦`new`是关键字,`delete`似乎也需要." (8认同)
  • @MartinBonner感谢您的建议,但我认为它很好.没有第二段的人可能不清楚最后一段.他们可能会问 - "为什么没有好办法?当然,请参阅`make_tuple`" (3认同)

axi*_*iac 14

也许这不是最好的参考,但这就是维基百科关于C++中的位置的new说法:

在早期版本的C++中,没有放置new的东西; 相反,开发人员this在构造函数中使用显式赋值来实现类似的效果.这种做法后来被废弃和废除,第三版"C++编程语言"没有提到这种技术.大约在1995年,编译器增加了对放置新操作员的支持.

也许在2017年,可以实现new标准库函数.您建议的实施使用最近添加的语言功能(其中许多是在2010年之后).

然而,C++语言比较早(自1983年以来),并且在开始时没有可变参数模板,没有typename,没有放置new,没有转发引用.

在开始时只有常规new,它必须是当时的语言功能,因为没有办法将其实现为库函数.

  • 是的,"new"的重点在于它返回了正确类型的即用型指针,无需从`void*`转换.没有模板,除了关键字之外,其他任何方式都无法实现. (3认同)
  • Placement new是在1989年发布的Cfront 2.0中. (3认同)