These wrappers are used in classes with virtual destructors to cover two situations:
ensure that the correct operator delete
is called after the object's destruction via delete pClass;
statement
deletion of arrays allocated via new Class[N]
expression in the delete [] class_array;
statement to ensure the correct number of items gets deleted using the correct operator delete
and handle potential exceptions during the process
From my old article:
When class has a virtual destructor, compiler generates a helper
function - deleting destructor. Its purpose is to make sure that a
proper operator delete
gets called when destructing a class.
Pseudo-code for a deleting destructor looks like following:
virtual void * A::'scalar deleting destructor'(uint flags)
{
this->~A();
if (flags&1) A::operator delete(this);
};
The address of this function is placed into the vftable instead of the
destructor's address. This way, if another class overrides the virtual
destructor, operator delete
of that class will be called. Though in
real code operator delete
gets overriden quite rarely, so usually
you see a call to the default delete().
Sometimes compiler can also
generate a vector deleting destructor. Its code looks like this:
virtual void * A::'vector deleting destructor'(uint flags)
{
if (flags&2) //destructing a vector
{
array = ((int*)this)-1; //array size is stored just before the this pointer
count = array[0];
'eh vector destructor iterator'(this,sizeof(A),count,A::~A);
if (flags&1) A::operator delete(array);
}
else {
this->~A();
if (flags&1) A::operator delete(this);
}
};
For more details see also C++: Under the Hood by Jan Gray, one of the main developers of Visual C++.
I also recommend you to make some classes with custom operators new/delete and check the generated code.
delete object
in the original code might call the destructor with a non-null second argument, while a call to the destructor, say, because the object was on the stack and went out of scope would have a null second argument, and thus not try to deallocate memory which was on the stack. Am I understanding correctly?