4

为什么不能只是常规的函数调用?新的本质上是:

malloc(sizeof(Foo));
Foo::Foo();

虽然删除是

Foo:~Foo();
free(...);

那么为什么 new/delete 最终拥有自己的语法而不是常规函数呢?

4

5 回答 5

7

这是一个尝试:

new操作员调用该函数operator new()。类似地,delete运算符调用operator delete()函数(对于数组版本也是如此)。

那么这是为什么呢?因为允许用户覆盖operator new()不允许覆盖操作符new(这是一个关键字)。你重写operator new()(和删除)来定义你自己的分配器,但是,你不负责(或被允许)调用适当的构造函数和析构函数。new编译器在看到关键字时会自动调用这些函数。

如果没有这种二分法,用户可以覆盖该operator new()函数,但编译器仍然必须将其视为特殊函数并为正在创建的对象调用适当的构造函数。

于 2010-02-18T03:20:18.537 回答
4

您可以重载operator newoperator delete提供自己的分配语义。当您想要绕过默认堆分配器的行为时,这很有用。例如,如果您分配和释放大量固定大小的小型对象的实例,您可能希望使用池分配器进行内存管理。

像其他运算符一样拥有newdelete作为显式运算符使得使用 C++ 的运算符重载机制更容易表达这种灵活性。

对于auto堆栈上的对象,分配/构造函数调用和释放/析构函数调用基本上按照您的要求是透明的。:)

于 2010-02-18T03:07:22.550 回答
3

因为没有办法为函数提供编译时类型安全(malloc() 返回 void*,记住)。此外,C++ 试图消除即使是最轻微的已分配但未初始化的对象浮动的机会。还有一些没有默认构造函数的对象——对于这些,你如何将构造函数参数提供给函数?像这样的函数需要太多的特殊情况处理;更容易将其提升为语言功能。因此运算符new。

于 2010-02-18T03:12:09.673 回答
2

“new/delete”是 C++ 语言中的关键字(如“for”和“while”),而 malloc/calloc 是标准 C 库中的函数调用(如“printf”和“sleep”)。非常不同的野兽,比它们相似的语法可能更多。

主要区别在于“新建”和“删除”会触发额外的用户代码——特别是构造函数和析构函数。malloc 所做的一切都是留出一些内存供您使用。当为简单的普通旧数据(例如浮点数或整数)留出内存时,'new' 和 'malloc' 的行为非常相似。但是当你为一个类请求空间时,'new'关键字会留出内存,然后调用一个构造函数来初始化那个类。巨大差距。

于 2010-02-18T03:53:10.160 回答
1

为什么 C++ 对大于有单独的语法?为什么它不能只是一个常规的函数调用?

greaterThan(foo, bar);
于 2010-02-18T03:07:41.277 回答