C++ 为什么c++;对new&;删除?

C++ 为什么c++;对new&;删除?,c++,function,new-operator,delete-operator,C++,Function,New Operator,Delete Operator,为什么不能只是常规的函数调用呢?新的基本上是: malloc(sizeof(Foo)); Foo::Foo(); 而delete是 Foo:~Foo(); free(...); 那么,为什么new/delete最终拥有自己的语法而不是常规函数呢?您可以重载操作符new和操作符delete,以提供自己的分配语义。当您想要绕过默认堆分配器的行为时,这非常有用。例如,如果分配和取消分配一个固定大小的小对象的许多实例,则可能需要使用池分配器进行内存管理 像其他操作符一样,将new和delete作为显

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

malloc(sizeof(Foo));
Foo::Foo();
而delete是

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

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

您可以重载
操作符new
操作符delete
,以提供自己的分配语义。当您想要绕过默认堆分配器的行为时,这非常有用。例如,如果分配和取消分配一个固定大小的小对象的许多实例,则可能需要使用池分配器进行内存管理

像其他操作符一样,将
new
delete
作为显式操作符使用,使得使用C++的操作符重载机制更容易表达这种灵活性


对于堆栈上的
auto
对象,分配/构造函数调用和解除分配/析构函数调用基本上是透明的,正如您所要求的那样:
greaterThan(foo, bar);

'因为无法为函数提供complie时间类型安全性(记住,malloc()返回void*)。此外,C++试图消除甚至有一点点机会被分配但未初始化的对象浮动。还有一些没有默认构造函数的对象——对于这些对象,您如何向函数提供构造函数参数?这样的功能需要太多的特殊情况处理;更容易将其升级为语言功能。因此,操作员是新的。

这里有一个尝试:

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

为什么会这样?因为允许用户覆盖
operator new()
,但不能覆盖
new
运算符(这是一个关键字)。您重写
操作符new()
(和delete)以定义自己的分配器,但是,您不负责(或不允许)调用适当的构造函数和析构函数。当编译器看到
new
关键字时,会自动调用这些函数


没有这个二分法,用户可以重写<代码>运算符New()/Cux>函数,但是编译器仍然必须将此视为一个特殊函数,并调用适当的构造函数来创建对象。< /P> < P>“New /Delphi”是C++语言中的关键字(如‘Af'和‘while’’),而malloc/calloc是标准C库中的函数调用(如“printf”和“sleep”)。非常不同的野兽,比他们相似的语法可能透露的更多


主要区别在于“new”和“delete”会触发额外的用户代码,具体来说就是构造函数和析构函数。malloc所做的就是留出一些内存供您使用。当为简单的普通旧数据(例如浮点或整数)留出内存时,“new”和“malloc”的行为非常相似。但是,当您为类请求空间时,“new”关键字会留出内存,然后调用构造函数来初始化该类。差别很大。

您是否可以覆盖
新建
删除
运算符,使它们不会这样做(即针对单例)?(我是C++新手)。默认的
new
结果更像这样:
Foo*pNewFoo=(static_cast(malloc(sizeof(Foo))->Foo()
还请记住,对于失败的分配,不会考虑异常。新的语法对我来说看起来更清晰。现在我们已经开始了,它有点复杂了:
Foo*p=new(malloc(sizeof(Foo))Foo();
,其中
new(ptr)表达式中的类型
称为placement new,实际上是对构造函数的调用(用户代码不能直接调用构造函数)。它不是“自己的语法”。它是运算符语法。类似于不必编写+(2,2)的方式C++中的操作符不使用函数调用语法。检查Martin York在这个链接中的答案,如果操作符过载,它将是函数调用,不是吗?因为这将是一个不必要的、毫无意义的偏离C;而且浪费键盘。这听起来很深,但是我不明白。你能显示一些代码吗?@ Aon我的C有点生疏,但基本上如果您知道您在任何时候都需要3个对象,并且会频繁调用new/delete,那么您可以执行以下操作:Foo[3]pool;char[3]available={0,1,2};char top=2;Foo allocate(){return pool[available[top-->}void deallocate(Foo*Foo){available[++top]=Foo-pool;}这提供了O(1)分配(如果您遵守规则的话),而malloc必须扫描可用空间的空闲列表malloc本身是类型不安全的;但是New可以通过将其包装为:Foo*New(args){Foo*ans=(Foo*)malloc(sizeof(Foo));Foo::init(ans,args);}