18.1.6 type-specific new and delete
When the compiler sees the new or delete expression of the class type, it checks whether the class has operator new or operator delete members. If the class defines (or inherits) its own new and delete functions, the functions are used to allocate and release memory for objects. Otherwise, the standard library version of these functions is called.
1. new and delete Functions
If the class defines one of the two members, it should also define the other.
Class member operator new function must have the return type void * and accept the form parameters of the size_t type. The size_t parameter of the initialization function for memory allocation calculated by the new expression in bytes.
Class member operator delete function must have the return type void. It can be defined to accept a Single void * type parameter, or to accept two parameters, namely, void * And size_t type. The delete expression initializes the void * parameter with the delete pointer, which can be a null pointer. If the size_t parameter is provided, the size_t parameter is automatically initialized by the compiler with the byte size of the object specified by the first parameter.
These functions are implicitly static functions and do not need to be explicitly declared as static, although this is legal. The new and delete functions must be static, because they are used either before the object is constructed (operator new) or after the object is revoked (operator delete). Therefore, no members can manipulate these functions. Like any other static member function, new and delete can only directly access static members of the class.
2. array operators new [] and operators delete []
You can also define the operator new [] and operator delete [] members to manage arrays of the management type. If these operator functions exist, the compiler uses them instead of the global version.
3. overwrite specific memory allocation
If the class defines its new and delete members, the class user can determine the operator by using the global scope, and force the new or delete expressions to use the global library function.
Vector <int> * vec =: new Vector <int>;
: Delete vec;
Vector <int> * vec =: new Vector <int>;
: Delete vec. Even if the class defines its class-specific operator new, it calls the global operator new; delete.
If the new expression is used to call the global operator new function to allocate memory, the delete expression should also call the global operator delete function.
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
New (first_free) T (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;
}
From xufei96's column