Wrote placement new also to write placement delete
The main content of this article is an introduction to placement new and placement Delete, and under what circumstances to use placement new and placement Delete.
For Widget* pw=new Widget;
the statement, the statement does two things, the first thing is to apply for the memory area, and the second thing is to construct the object on that memory area, which is called the constructor. We envision one implementation, when the first thing is done, and the second thing goes wrong, so how do we deal with it, obviously we need to restore this part of the memory back, so how to restore back is the problem we need to solve.
At this point, the customer is not able to return the memory, because if the widget constructor throws an exception, then PW has not been assigned a value, the client hand pointer does not point to the open memory. The task of releasing memory falls to the C + + runtime system.
classwidget{ Public:Static void*operator New(STD:: size_t size,STD::ostream& LogStream)//non-normal form of new Throw(STD:: Bad_alloc);Static void operator Delete(void* Pmemory,STD:: size_t size)//Normal class-specific delete Throw(); ...... }; widget* PW =New(STD::Cerr) Widgets;
We see the code above, when we call the new(std::cerr) Widget
statement, we go into the widget's custom new function, and when an exception occurs in the constructor, we can call the corresponding delete function in the constructor to implement memory reclamation. If you get the signature, it's easy to reclaim the memory.
Let's start with the introduction of placement new and placement Delete, the term placement new means new with additional parameters, such as void* operator new(std::size_t, void* pMemory) throw();
placement Delete, with the additional parameters.
The key to solving the problem becomes how to get the right delete.
According to the author's instructions, we know
Placement Delete is called only if there is an exception to the constructor triggered by the placement new call. Execution of a delete on a pointer will never cause a call to placement delete.
This means that for all placement new we must provide both a normal delete and a placement version.
classDerived: Publicbase{ Public: ......Static void*operator New(STD:: size_t size)Throw(STD:: Bad_alloc);//re-declare the normal form of new}; derived* pd=New(STD::Clog) Derived;//error, because base's placement new is covered upderived* pd1=NewDerived;//CorrectBy default, C + + provides the following form within the global scopeoperator New:void*operator(STD:: size_t)Throw(STD:: Bad_alloc);//normal New void*operator(STD:: size_t,void*)Throw();//placement New void*operator(STD:: size_t,Const STD::nothrow_t&)Throw();//nothrow Newclassstadardnewdeleteforms{ Public://normal Static void*operator New(STD:: size_t size)Throw(STD:: Bad_alloc) {return::operator New(size);}Static void operator Delete(void* pmemory)Throw() {::operator Delete(pmemory);}//placement Static void*operator New(STD:: size_t size,void* ptr)Throw(STD:: Bad_alloc) {return::operator New(size, PTR);}Static void operator Delete(void* Pmemory,void* ptr)Throw() {::operator Delete(Pmemory, PTR);}//nothrow Static void*operator New(STD:: size_t size,Const STD::nothrow_t& NT)Throw(STD:: Bad_alloc) {return::operator New(SIZE,NT);}Static void operator Delete(void* Pmemory,Const STD::nothrow_t&)Throw() {::operator Delete(pmemory);} };classWidgets: Publicstandardnewdeleteforms{ Public://Make these forms visible usingStandardnewdeleteforms::operator New;usingStandardnewdeleteforms::operator Delete;//Add your own defined Static void*operator New(STD:: size_t size,STD::ostream& LogStream)Throw(STD:; bad_alloc);Static void operatorDetele (STD:: size_t size,STD::ostream& LogStream)Throw(); };
Effective C + + clause 52