哪个运营商删除?

时间:2010-08-27 18:56:08

标签: c++ operators

之间是否存在差异:

operator delete(some_pointer);

delete some_pointer;

如果是,那么有什么区别,哪一个应该使用哪个以及该运营商的另一个版本? 感谢。

4 个答案:

答案 0 :(得分:22)

具有讽刺意味的是,delete运算符与operator delete()不是一回事。

delete some_pointer;调用some_pointer指向的对象的析构函数,然后调用operator delete()释放内存。

您通常不直接调用operator delete(),因为如果这样做,将不会调用该对象的析构函数,并且您可能最终导致内存泄漏。

您唯一需要关心operator delete()的时候是想要通过覆盖operator new()operator delete()进行自己的内存管理。

最重要的是,您还应该知道deletedelete []是两回事。

答案 1 :(得分:6)

operator delete()只是释放内存。 delete some_pointer调用some_pointer的析构函数,然后调用operator delete()

答案 2 :(得分:2)

delete some_pointer;是要使用的“正确”。

operator delete(some_Pointer);主要作为定义您自己的删除操作符的语法工件存在。也就是说,因为您将加号运算符定义为;

 myclass::operator+(myclass b) {....}

你真的可以写:

 myclass c = a.operator+(b);

但没有人这样做过。他们使用:

 myclass c = a + b;

同样,你可以写operator delete(some_Pointer);,但没有人写过。

答案 3 :(得分:2)

至少根据我的经验,实施 operator newoperator delete比实际使用(即调用)它们更为常见,至少是直接使用它们。

通常,您间接使用operator newoperator delete - 您可以编写new expression,例如A *a = new A;。为了实现这一点,编译器生成调用operator new来分配原始内存的代码,然后调用A::A将原始内存转换为A对象,就像你写的那样:

void *temp = operator new(sizeof A);  // allocate raw memory with operator new
A *a = new(temp) A;                   // convert raw memory to object with placement new

完成对象后,使用delete A;。为了实现这一点,编译器调用对象的dtor,然后释放内存,大致就像你做的那样:

a->~A();
operator delete(a);

还有operator [] newoperator [] delete,它们在/ /如果您分配/删除数组时使用 - 但正常版本和数组版本之间没有任何实际区别 - 他们都只是分配了一定数量的原始内存(尽管你可能猜测数组版本将分配相对大量的内存,并在此基础上进行一些优化。)

在任何情况下,如果要优化为特定类的对象分配内存的方式,请重载这些内容以执行此操作。您可以插入和使用相当多的现有实现,尤其是在您希望分配大量微小对象的情况下,因此您需要最小化与每个分配相关的开销(例如HeapLayers ,Loki的小块分配器。)

一个有趣的小花絮:operator newoperator [] newoperator delete和operator []在声明/定义中删除are always静态class members, even if you don't explicitly include静态。< / p>

还有全部版本的全部版本(::operator new::operator [] new::operator delete::operator [] delete)。它们标志着“内部”C ++内存管理与外部世界之间的“边界”。通常,它们从操作系统分配相对较大的内存块,然后根据请求将较小的内容返回到程序的其余部分。如果您希望(尝试)优化整个程序的内存管理,通常可以通过重载(或实际上,替换)这些来实现。同样,典型的原因是如果你期望分配很多小对象(但不只是在几个类中)。其中一个例子是Boost Pool库。

直接使用上述任何内容通常仅限于需要原始内存块,不是对象的情况。一个例子是实现自己的容器类。例如,std::vector通常使用::operator new(通过Allocator对象)来分配用于存储对象的内存。由于它需要能够分配存储,但只能在以后(或者可能永远不会)创建该存储中的对象,它不能只使用像data = new T[size];这样的东西 - 它必须分配原始内存,然后使用新的位置在将它们添加到集合中时(例如,当您push_back对象时)在内存中创建对象。 std::deque也是如此。如果您希望(例如)“从头开始”实现自己的循环缓冲区,直接处理所有内存管理而不是使用vector之类的东西进行存储,您可能需要/想要做同样的事情