Previous: http://www.bkjia.com/kf/201201/116032.html
18.1.3 operator new function and operator delete function
When using the new expression, there are actually three steps. First, this expression calls the standard library function named operator new and allocates enough original untyped memory to save an object of the specified type. Next, run a constructor of this type to construct an object with the specified initialization type. Finally, a pointer to the newly allocated and constructed object is returned.
Two steps are taken when the delete expression delete sp is used to delete the dynamically assigned object. First, run the appropriate destructor on the object pointed to by sp. Then, call the standard library function named operator delete to release the memory used by the object.
The names of standard library functions operator new and operator delete are easy to misunderstand. Unlike other opertaor functions (such as operator =), these functions do not overload new or delete expressions. In fact, we cannot redefine the behavior of new and delete expressions.
Call the operator new function to execute the new expression to obtain the memory, construct an object in the memory, undo the delete expression, and then call the operator delete function, to release the memory used by the object.
Because the new (or delete) expression and the standard library function have the same name, the two are easy to confuse.
1. operator new and operator delete Interfaces
Operator new and operator delete functions have two overloaded versions. Each version supports related new expressions and delete expressions.
Void * operator new (size_t); // allocate an object
Void * operator new [] (size_t); // allocate an array
Void operator delete (void *); // delete memory of an object
Void operator delete [] (void *); // delete memory of an array
Void * operator new (size_t); // allocate an object
Void * operator new [] (size_t); // allocate an array
Void operator delete (void *); // delete memory of an object
Void operator delete [] (void *); // delete memory of an array
2. Use the allocation operator Function
Although operator new and operator delete functions are designed to be used by new expressions, they are usually available functions in the standard library. They can be used to obtain unconstructed memory, which is somewhat similar to allocate and deallocate members of the allocator class.
Template <class T>
Class Vector {
Public:
Vector (): elements (0), first_free (0), end (0 ){}
Void push_back (const T &);
Void * operator new [] (size_t); // allocate an array
Void operator delete [] (void *); // delete memory of an array
Private:
Static std: allocator <T> alloc;
Void reallocate ();
T * elements; // first element
T * first_free; // behind the last actual element
T * end; // behind vector conent
};
Template <class T>
Void Vector <T >:: push_back (const T & t ){
If (first_free = end)
Reallocate (); // gets more space and copies existing elements to it
Alloc. construct (first_free, t );
++ First_free;
}
Template <class T>
Void Vector <T >:: reallocate (){
Std: ptrdiff_t size = first_free-elements;
Std: ptrdiff_t newcapacity = 2 * max (size, 1 );
T * newelements = static_cast <T *> (alloc. operator new [] (newcapacity ));
Uninitialized_copy (elements, first_free, newelements );
For (T * p = first_free; p! = Elements ;){
Alloc. destroy (-- p );
}
If (elements)
Alloc. operator delete [] (elements, end-elements );
Elements = newelements;
First_free = elements + size;
End = elements = newcapacity;
}
Template <class T>
Class Vector {
Public:
Vector (): elements (0), first_free (0), end (0 ){}
Void push_back (const T &);
Void * operator new [] (size_t); // allocate an array
Void operator delete [] (void *); // delete memory of an array
Private:
Static std: allocator <T> alloc;
Void reallocate ();
T * elements; // first element
T * first_free; // behind the last actual element
T * end; // behind vector conent
};
Template <class T>
Void Vector <T >:: push_back (const T & t ){
If (first_free = end)
Reallocate (); // gets more space and copies existing elements to it
Alloc. construct (first_free, t );
++ First_free;
}
Template <class T>
Void Vector <T >:: reallocate (){
Std: ptrdiff_t size = first_free-elements;
Std: ptrdiff_t newcapacity = 2 * max (size, 1 );
T * newelements = static_cast <T *> (alloc. operator new [] (newcapacity ));
Uninitialized_copy (elements, first_free, newelements );
For (T * p = first_free; p! = Elements ;){
Alloc. destroy (-- p );
}
If (elements)
Alloc. operator delete [] (elements, end-elements );
Elements = newelements;
First_free = elements + size;
End = elements = newcapacity;
} These functions are similar to the allocate and deallocate members of the allocator class. However, they differ in an important aspect: they operate on void * pointers instead of typed pointers.
In general, using allocator is more type-safe than directly using operator new and operator delete functions.
The allocate member allocates typed memory, so the program that uses it does not need to calculate the amount of memory required in bytes, they can also avoid forced type conversion on the return values of operator new. Similarly, deallocate releases a specific type of memory and does not need to be converted to void *.
From xufei96's column