Which operator delete?

前端 未结 4 1498
[愿得一人]
[愿得一人] 2021-01-01 21:44

Is there a difference between:

operator delete(some_pointer);

and

delete some_pointer;

and if so what is

相关标签:
4条回答
  • 2021-01-01 21:55

    delete some_pointer; is the "correct" one to use.

    operator delete(some_Pointer); exist mainly as an artifact of the syntax for defining you own delete operator. That is, because you define an plus operator as;

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

    you really could write:

     myclass c = a.operator+(b);
    

    but no one ever does that. They use:

     myclass c = a + b;
    

    Similarly, you could write operator delete(some_Pointer);, but no one ever does.

    0 讨论(0)
  • 2021-01-01 22:11

    operator delete() simply frees the memory. delete some_pointer calls some_pointer's destructor, and then calls operator delete().

    0 讨论(0)
  • 2021-01-01 22:20

    At least in my experience, it's more common to implement operator new and operator delete than to actually use (i.e., call) them, at least directly.

    Usually, you use operator new and operator delete indirectly -- you write a new expression, like A *a = new A;. To implement this, the compiler generates code that invokes operator new to allocate raw memory, then invokes a A::A to convert that raw memory into an A object, much as if you'd written:

    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
    

    When you're done with the object, you use delete A;. To implement that, the compiler invokes the dtor for the object, and then frees the memory, roughly like you'd done:

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

    There are also operator [] new and operator [] delete, which are used when/if you allocate/delete arrays -- but there isn't necessarily any real difference between the normal version and the array version -- they both just allocate a specified amount of raw memory (though you might guess that the array versions will allocate relatively large amounts of memory, and do some optimization on that basis).

    In any case, if you want to optimize how memory is allocated for objects of a particular class you overload these to do it. There are a fair number of existing implementations that you can drop-in and use, especially for situations where you expect to allocate a large number of tiny objects so you need to minimize the overhead associated with each allocation (e.g., HeapLayers, Loki's small block allocator).

    One interesting little tidbit: operator new, operator [] new, operator delete and operator [] deleteare alwaysstaticclass members, even if you don't explicitly includestatic` in their declaration/definition.

    There are also global versions of all four (::operator new, ::operator [] new, ::operator delete and ::operator [] delete). These mark the "border" between the "internal" C++ memory management, and the outside world. Typically they allocate relatively large chunks of memory from the operating system, and then return smaller pieces to the rest of the program upon request. If you want to (try to) optimize memory management for your entire program, you typically do it by overloading (or, really, replacing) these. Again, the typical reason would be if you expect to allocate a lot of small objects (but not in just a few classes). One example of this is the Boost Pool library.

    Direct use of any of the above is generally restricted to situations where you need a block of raw memory, not objects. One example would be implementing your own container classes. For example, std::vector normally uses ::operator new (via an Allocator object) to allocate memory in which to store objects. Since it needs to be able to allocate storage, but only later (or perhaps never) create objects in that storage, it can't just use something like data = new T[size]; -- it has to allocate raw memory, then use placement new to create objects in the memory as you add them to the collection (e.g., when you push_back an object). The same is true with std::deque. If you wanted (for example) to implement your own circular buffer "from the ground up", handling all the memory management directly instead of using something like vector for storage, you'd probably need/want to do the same.

    0 讨论(0)
  • 2021-01-01 22:21

    Ironically, the delete operator and operator delete() are not the same thing.

    delete some_pointer; calls the destructor of the object pointed to by some_pointer, and then calls operator delete() to free the memory.

    You do not normally call operator delete() directly, because if you do, the object's destructor will not be called, and you are likely to end up with memory leaks.

    The only time you have to care about operator delete() is when you want to do your own memory management by overriding operator new() and operator delete().

    To top it off, you should also be aware that delete and delete [] are two different things.

    0 讨论(0)
提交回复
热议问题