为什么它不能只是常规函数调用?新的本质上是:
malloc(sizeof(Foo));
Foo::Foo();
删除时
Foo:~Foo();
free(...);
那么为什么new / delete最终会拥有自己的语法而不是常规函数呢?
答案 0 :(得分:7)
这是一个刺痛:
new
运算符调用operator new()
函数。同样,delete
运算符调用operator delete()
函数(类似于数组版本)。
那为什么呢?因为允许用户覆盖operator new()
但不 new
运算符(这是一个关键字)。您重写operator new()
(和删除)以定义您自己的分配器,但是,您不负责(或允许)调用适当的构造函数和析构函数。编译器在看到new
关键字时会自动调用这些函数。
如果没有这种二分法,用户可以覆盖operator new()
函数,但编译器仍然必须将其视为特殊函数并为对象调用相应的构造函数(s)正在创建。
答案 1 :(得分:4)
您可以重载operator new
和operator delete
以提供自己的分配语义。当您想绕过默认堆分配器的行为时,这很有用。例如,如果分配和释放大量固定大小对象的大量实例,则可能需要使用池分配器进行内存管理。
将new
和delete
作为显式运算符与其他运算符一样,使用C ++的运算符重载机制可以更容易地表达这种灵活性。
对于堆栈上的auto
个对象,分配/构造函数调用和释放/析构函数调用在您请求时基本上是透明的。 :)
答案 2 :(得分:3)
'因为没有办法用函数提供complie-time类型的安全性(malloc()返回void *,请记住)。此外,C ++试图消除分配但未初始化的对象的最轻微机会。并且有没有默认构造函数的对象 - 对于这些,你如何将构造函数参数提供给函数?像这样的功能需要太多的特殊情况处理;更容易将其推广到语言功能。因此,操作员新。
答案 3 :(得分:2)
'new / delete'是C ++语言中的关键字(如'for'和'while'),而malloc / calloc是标准C库中的函数调用(如'printf'和'sleep')。非常不同的野兽,超过他们类似的语法可能会让步。
主要区别在于'new'和'delete'会触发其他用户代码 - 特别是构造函数和析构函数。所有malloc都会留出一些内存供您使用。为简单的普通旧数据(例如浮点数或整数)预留内存时,'new'和'malloc'的行为非常相似。但是当你为一个类请求空间时,'new'关键字会留出内存,然后调用构造函数来初始化该类。差异很大。
答案 4 :(得分:1)
为什么C ++有大于?的单独语法?为什么它不能只是一个常规的函数调用?
greaterThan(foo, bar);