● General Concepts
Widget * PW = new widget;
There are two steps:
1> call operator new to allocate memory
2> call the ctor initialization object
If an exception is thrown in step 2, the system automatically calls
1> void operator Delete (void * MEm) Throw ();
2> void Widget: Operator Delete (void * MEM, STD: size_t size) Throw ();
Memory is recycled.
The system searches for the delete statement corresponding to the new statement. If no placement Delete is provided for a placement new, memory cannot be recycled.
Therefore, a one-to-one correspondence must be maintained during custom new/delete operations:
Class widget {<br/> Public: <br/> static void * operator new (STD: size_t size, STD: ostream & log) Throw (STD: bad_alloc ); <br/> static void operator Delete (void * pmemory, STD: ostream & log) Throw (); <br/>... <br/>}; <br/> widget * PW = new (STD: cerr) widget;
If an exception occurs, the system automatically finds the delete with ostream.
● There is a placement new in STL:
Void * operator new (STD: size_t, void * pmemory) Throw ();
This function is used by the vector to search for storage locations for new objects internally. This is why placement new is named. Placement refers to the term "placement, finding a proper location.
In general, as long as the new with redundant parameters is called Placement new. When the system matches placement new and placement Delete, it also relies on comparing redundant parameters.
● Item 33 describes how to define occlusion when a class is derived from a duplicate name:
Class base {<br/> Public: <br/> static void * operator new (STD: size_t size, STD: ostream & log) Throw (STD: bad_alloc ); <br/>... <br/>}; <br/> base * pb = new base; // error! The default new is blocked <br/> base * pb = new (STD: cerr) base; // correct <br/> class derived: public base {<br/> Public: <br/> // This is amazing. It blocks the base class. <br/> static void * operator new (STD :: size_t size) Throw (STD: bad_alloc); <br/>... <br/>}; <br/> derived * Pd = new (STD: clog) derived; // error <br/> derived * Pd = new derived; // OK
First, we need to understand C ++'s predefined New:
Void * operator new (STD: size_t) Throw (STD: bad_alloc); // normal New <br/> void * operator new (STD: size_t, void *) throw (); // placement new <br/> void * operator new (STD: size_t, const STD: nothrow_t &) Throw (); // No-throw new
You need to redefine these items in your class.
The procedure is as follows:
Class standardnewdeleteforms {<br/> Public: <br/> // normal New/delete <br/> static void * operator new (STD: size_t size) Throw (STD :: bad_alloc) <br/> {return: Operator new (size) ;}< br/> static void operator Delete (void * pmemory) Throw () <br/> {:: operator Delete (pmemory) ;}< br/> // placement new/delete <br/> static void * operator new (STD: size_t size, void * PTR) Throw () <br/> {return: Operator new (size, PTR) ;}< br/> static void operator Delete (void * pmemory, void * PTR) Throw () <br/> {return: Operator Delete (pmemory, PTR) ;}< br/> // nothrow new/delete <br/> static void * operator new (STD :: size_t size, const STD: nothrow_t & NT) Throw () <br/> {return: Operator new (size, NT );} <br/> static void operator Delete (void * pmemory, const STD: nothrow_t &) Throw () <br/>{:: Operator Delete (pmemory );} <br/>}; <br/> // If You Want To customize new, you must derive from standardnewdeleteforms. <br/> class Widget: Public standardnewdeleteforms {<br/> public: <br/> // use using to declare the Standard <br/> using standardnewdeleteforms: Operator new; <br/> using standardnewdeleteforms: Operator Delete; <br/> // define your own <br/> static void * operator new (STD: size_t size, STD: ostream & log) Throw (STD :: bad_alloc); <br/> static void operator Delete (void * pmemory, STD: ostream & log) Throw (); <br/>... <br/> };