为什么语言中内置了非放置的“new”和“delete”,而不仅仅是常规函数?
Why are non-placement `new` and `delete` built into the language and not just regular functions?
为什么非放置 new
expression and the delete
expression 作为语言内置而不是常规函数实现?
如果我们有...
一种requesting/giving将内存返回到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 */
}
如果它们已经作为独立函数提供,则不可能为它们提供用户定义的替换。
例如现在根据标准,编写我自己的 globl new
和 delete
是合法的,它们将在整个程序中使用。
18.6.2 Storage allocation and deallocation [new.delete]
2 Replaceable: A C ++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C ++ standard library.
如果像其他库函数一样提供这些函数,那么每次正常调用 new
或 delete
都会导致 "more than one instance of overloaded function matches arguments" 错误。
如果用户的目标是在某个内存位置创建一个对象,那么 new
似乎是一种自然的方法,因为 转发引用、可变参数templates 和 placement new 在那些日子里还不是什么东西。正如 正确指出的那样,模板于 1990 年发布,并于 1989 年新增。另一方面,可变参数模板仅在 C++11 中成为 C++ 的一部分。
tl;dr 无法将一堆参数转发给任意类型的构造函数(就像现在可以使用 make
函数那样)。
也许这不是最好的参考,但这是维基百科关于 C++ 中 placement new
的说法:
In earlier versions of C++ there was no such thing as placement new; instead, developers used explicit assignment to this
within constructors to achieve similar effect. This practice has been deprecated and abolished later, and third edition of The "C++ Programming Language" doesn't mention this technique. Support for placement new operator has been added to compilers circa 1995.
也许在 2017 年可以将 new
作为标准库函数实现。您建议的实现使用最近添加的语言功能(其中许多是在 2010 年之后)。
然而,C++ 语言要古老得多(自 1983 年以来)并且在开始时没有可变参数模板,没有 typename
,没有放置 new
,没有转发引用。
一开始只有正则new
,当时只能作为语言特性,因为没有办法将其作为库函数来实现
为什么非放置 new
expression and the delete
expression 作为语言内置而不是常规函数实现?
如果我们有...
一种requesting/giving将内存返回到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 */
}
如果它们已经作为独立函数提供,则不可能为它们提供用户定义的替换。
例如现在根据标准,编写我自己的 globl new
和 delete
是合法的,它们将在整个程序中使用。
18.6.2 Storage allocation and deallocation [new.delete]
2 Replaceable: A C ++ program may define functions with either of these function signatures, and thereby displace the default versions defined by the C ++ standard library.
如果像其他库函数一样提供这些函数,那么每次正常调用 new
或 delete
都会导致 "more than one instance of overloaded function matches arguments" 错误。
如果用户的目标是在某个内存位置创建一个对象,那么 new
似乎是一种自然的方法,因为 转发引用、可变参数templates 和 placement new 在那些日子里还不是什么东西。正如
tl;dr 无法将一堆参数转发给任意类型的构造函数(就像现在可以使用 make
函数那样)。
也许这不是最好的参考,但这是维基百科关于 C++ 中 placement new
的说法:
In earlier versions of C++ there was no such thing as placement new; instead, developers used explicit assignment to
this
within constructors to achieve similar effect. This practice has been deprecated and abolished later, and third edition of The "C++ Programming Language" doesn't mention this technique. Support for placement new operator has been added to compilers circa 1995.
也许在 2017 年可以将 new
作为标准库函数实现。您建议的实现使用最近添加的语言功能(其中许多是在 2010 年之后)。
然而,C++ 语言要古老得多(自 1983 年以来)并且在开始时没有可变参数模板,没有 typename
,没有放置 new
,没有转发引用。
一开始只有正则new
,当时只能作为语言特性,因为没有办法将其作为库函数来实现