之间是否存在差异:
operator delete(some_pointer);
和
delete some_pointer;
如果是,那么有什么区别,哪一个应该使用哪个以及该运营商的另一个版本? 感谢。
答案 0 :(得分:22)
具有讽刺意味的是,delete
运算符与operator delete()
不是一回事。
delete some_pointer;
调用some_pointer
指向的对象的析构函数,然后调用operator delete()
释放内存。
您通常不直接调用operator delete()
,因为如果这样做,将不会调用该对象的析构函数,并且您可能最终导致内存泄漏。
您唯一需要关心operator delete()
的时候是想要通过覆盖operator new()
和operator delete()
进行自己的内存管理。
最重要的是,您还应该知道delete
和delete []
是两回事。
答案 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 new
和operator delete
比实际使用(即调用)它们更为常见,至少是直接使用它们。
通常,您间接使用operator new
和operator 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 [] new
和operator [] delete
,它们在/ /如果您分配/删除数组时使用 - 但正常版本和数组版本之间没有任何实际区别 - 他们都只是分配了一定数量的原始内存(尽管你可能猜测数组版本将分配相对大量的内存,并在此基础上进行一些优化。)
在任何情况下,如果要优化为特定类的对象分配内存的方式,请重载这些内容以执行此操作。您可以插入和使用相当多的现有实现,尤其是在您希望分配大量微小对象的情况下,因此您需要最小化与每个分配相关的开销(例如HeapLayers ,Loki的小块分配器。)
一个有趣的小花絮:operator new
,operator [] new
,operator 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
之类的东西进行存储,您可能需要/想要做同样的事情