Destructor against overloading

What is the purpose of having both a destructor and an overload delete

for a class?

In what scenarios should you use both?

+3


source to share


4 answers


When you allocate an object with an expression new

like:

X *x = new X();

      

It basically does two separate things: 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 one simply allocates a block of raw memory. The second simply takes that block of raw memory and creates an object in it.

On the contrary, the object is deleted:

delete x;

      

... is roughly equivalent to something like:



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

      

Thus, the new operator and the delete operator simply deal with the allocation and deallocation of raw memory. The constructor and destructor simply deal with the creation and destruction of objects in memory that have already been allocated. After the destructor works to destroy an object in some memory, it operator delete

is then used to free the memory itself.

By default, there is one global pair operator new

and operator delete

, which are used to select objects of all types. You can replace them if you like. You can also provide operator new

, and operator delete

for a certain class (as static member functions 1 ). In this case, these functions will only be used to manage memory for objects of this class. This is generally especially useful for things like very small classes, and you expect to allocate a large number of objects of that class. Many memory managers are not particularly efficient when dealing with an extremely large number of extremely small items, so overloading in this case can improve (reduce) memory usage a little.

There are also operator new[]

and operator delete[]

that are used when / if you allocate / deallocate arrays of objects. operator new[]

it just passes the number of bytes to allocate, and operator delete

just passes a block of raw memory to be freed. If you choose to overload them, you can assume that they will be used mainly for large blocks of memory and will be optimized accordingly, but that is the only difference from the non-array versions.

Typically, I would avoid using new

arrays for distribution (ever), which made them completely irrelevant. And no, they cannot be / are not used by the allocator if you create something like std::vector<T>

. Well, I suppose if you don't mind misusing the system thoroughly enough, you can create an allocator to use with the std::vector

one you used new char[size]

to control the allocation, in which case it would use one of them, but I find it hard to imagine someone will actually do it. Perhaps once when C ++ was not well understood, but nowadays it will stick like a sore thumb on any decent codebase.


1. One minor oddity: the compiler "knows" they must always be static, so even if you don't use the keyword static

when declaring / defining them, they will still be static.

+5


source


The answer becomes clear when you understand that constructor / destructor and new / delete pairs serve orthogonal purposes:

  • Constructors and destructors allow your class to control the acquisition and release of resources that your class owns. They do not include memory for the object itself.
  • Operators new

    and delete

    let your class control the process of collecting and freeing memory allocated to an instance of the class itself.


It is also important to understand that the challenges new

and delete

embody calls constructors and destructors: new

going to the constructor, and delete

occurs after the destructor. Although the destructor can treat the contents of an object as "alive", the operator delete

must treat it as "dead"; in particular, it tries to reference any of the members or call any member functions of a class from delete

undefined.

The answer should now be clear: you implement one or the other, or both, depending on what your program wants to control.

+3


source


As far as I understand, the destructor is meant to implement class-specific behavior like freeing allocated resources and the like, while operator overloading is delete

meant to manage user memory that is not class specific or is not intended for a single class as described here . As a rule, you do not need to overload new

and delete

.

+1


source


A destructor is used to destroy an instance of a class (object) regardless of whether it is assigned on the stack as an automatic variable or on the heap with an operator new

.

Overloaded new

and delete

will only be used for memory allocation when your code uses the new

and operators delete

.

Note that new

both delete

are static and operate on void (unstructured) memory. They cannot access class members via (implicit or explicit) this

. You can pass this memory to your object and initialize / reset, but they are not meant to do that.

0


source







All Articles