Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Destructor vs Overloading delete

What exactly is the purpose of having both a destructor and Overloading delete for a class?

In what types of scenarios should one use both?

like image 753
flakes Avatar asked Oct 19 '25 18:10

flakes


1 Answers

When you allocate an object with a new expression like:

X *x = new X();

It basically does two separate things: it allocates some memory, then creates an object in that memory, roughly equivalent to:

void *temp = operator new(sizeof(X));
X *x = new(temp) X;

The first just allocates a block of raw memory. The second just takes that block of raw memory, and creates an object in it.

Roughly the reverse happens when you delete an object:

delete x;

...is roughly equivalent to something like:

x->~X();
operator delete(static_cast<void *>(x));

So, operator new and operator delete just deal with allocating and freeing raw memory. The constructor and destructor just deal with creating and destroying objects in memory that's already been allocated. After the destructor runs to destroy the object in some memory, then operator delete is used to free the memory itself.

By default, there's one global pair of operator new and operator delete that are used to allocate objects of all types. You can replace those if you want. You can also provide an operator new and operator delete for a specific class (as static member functions1). In this case, those functions will be used only for managing memory for objects of that class. This tends to be particularly useful for things like classes that are extremely small, and you expect to allocate a large number of objects of this class. Many memory managers aren't particularly efficient when dealing with an extremely large number of extremely small items, so overloading in this case can improve (reduce) memory usage quite a bit.

There are also operator new[] and operator delete[], which are used when/if you allocate/free arrays of objects. operator new[] is just passed a number of bytes to allocate, and operator delete is just passed a block of raw memory to free. If you decided to overload these, you might presume that they'd be used primarily for larger blocks of memory and optimize appropriately, but that's about the only difference from the non-array versions.

As a rule, I'd avoid using new to allocate arrays (ever) rendering these entirely irrelevant. And no, they can't be/aren't used by an allocator if you create something like an std::vector<T> either. Well, I suppose if you didn't mind abusing the system quite thoroughly, you could create an allocator for use with std::vector that used new char[size] to manage the allocation, in which case it would use one of these, but I find it hard to imagine that anybody would really do that. Maybe at one time when C++ wasn't well understood, but nowadays it would stick out like a sore thumb in any decent code base.


1. One minor oddity: the compiler "knows" these must always be static, so even if you don't use the static key-word when you declare/define them, they'll be static anyway.

like image 58
Jerry Coffin Avatar answered Oct 22 '25 07:10

Jerry Coffin