Brief explanation
1.operator New is a memory allocation function (same as malloc), and C + + provides 3 default operator new implementations within the global scope, and users can reload operator new.
1 void*operator New(std::size_t)Throw(Std::bad_alloc);//normal New2 void*operator New(std::size_t,Conststd::nothrow_t&)Throw();//nothrow New3 void*operator New(std::size_t,void*)Throw();//Placement New
The following two lines of code are equivalent, are allocated a piece of the size of sizeof (widget) memory and return a pointer, there is no execution constructor .
1 widget *a= (widget*)::operatornew(sizeof); 2 widget *b= (widget*) malloc (sizeof(widget));
2.new/new operator is the new operator built into C + +.
// here, a new Widget object is split into two steps . // 1. Run-time system call operator new opens sizeof (widget)-sized memory // 2. Construct a Widget object widget on the memory address *c=new widget ();
Our usual new operation is called by the runtime system operator new, and then the constructor is called to initialize. This process is not redefined. That is, programmers cannot overload C + + built-in new operators. The only operator we can reload is the New/operator new[], which is the part that allocates memory.
3.placement New is an overloaded version of operator new on the global scope, as we saw on the
1 void operator New (std::size_t,voidthrow(); // Placement New
Placement new does not allocate memory, but instead returns a pointer to the allocated memory, which is the void * in the function argument list, which is "a pointer to the allocated memory you just passed in".
STD:: the implementation of this function:
1 void operator New void* __p) _noexcept {return __p;}
So why do we need this placement new?
The answer is: when you need to construct an object in an allocated memory, calling the usual new widget () opens up another memory space rather than constructing the widget () object at a known address.
// This applies a memory space first, held by the pointer Widget*a, and does not call the constructor // then we use placement new to construct the Widget object on the a address . // here:: Represents the call to the matching function widget in global scope *a= (widget*):: operatornew(sizeof( Widget);::new(a) widget ();
A further discussion
1.placement New is essentially a operator new with additional arguments, and generally we refer to placement new as the overloaded version of the extra argument void* (which has been included in the C + + standard library). These names have no effect on our discussion, as long as we know that placement new is also a operator new. But don't forget that we can reload other versions of placement new, such as the extra arguments for Std::ostream&, and provide the log function.
1#include <iostream>2 classWidgets3 {4 Public:5 Static void*operator New(std::size_t _size,std::ostream&o)6 {7o<<"void * operator new (std::size_t _size,ostream& o)"<<Std::endl;8 return::operator New(_size);9 }Ten widgets () One { Astd::cout<<"widgets ()"<<Std::endl; - }; -~widgets () the { -std::cout<<"~widget ()"<<Std::endl; - }; - + }; - intMain () + { A //The following two construction methods are equivalent at //constructs a Widget object and uses the log function of the operator new -widget* a= (widget*) Widget::operator New(sizeof(widgets), std::cout); -::New(a) widgets (); - - //also constructs a Widget object, and uses the log function of the operator new -widget* b=New(std::cout) widget (); in return 0; -}
In this sample code, I overloaded the placement new in the class, with the additional parameter ostream&.
2. Note the scope masking problem. If you overload a operator new in a class, when you use the new operator for this class and its subclasses, it obscures the operator new in the global scope, and the compiler discovers that the inner scope (within the class) has a operator new declaration, Instead of finding the global scope for additional operator new declarations, it goes directly to the parameter matching stage, and throws a compilation error if you reload the operator new parameter and the call does not match.
The workaround is that if operator new is overloaded within the class, and you still have the possibility to use operator new in the global scope, you also overload the operator new with the global scope , ensuring that the call succeeds.
Create a base class for your class that contains the global scope of the same type operator new, so that it calls operator new within the global scope.
1#include <iostream>2 classglobalscopenew3 {4 Public:5 Static void*operator New(std::size_t size)Throw(Std::bad_alloc)6 {7 return::operator New(size);8 }9 Static void*operator New(std::size_t size,Conststd::nothrow_t& t)Throw()Ten { One return::operator New(size, t); A } - Static void*operator New(std::size_t size,void* p)Throw() - { the return::operator New(size, p); - } - - }; + classWidgets: Publicglobalscopenew - { + Public: A usingGlobalscopenew::operator New; at Static void*operator New(std::size_t _size,std::ostream&o) - { -o<<"void * operator new (std::size_t _size,ostream& o)"<<Std::endl; - return::operator New(_size); - } - widgets () in { -std::cout<<"widgets ()"<<Std::endl; to }; +~widgets () - { thestd::cout<<"~widget ()"<<Std::endl; * }; $ Panax Notoginseng }; - intMain () the { +widget* w2=New(std::cout) widget (); A //This call was not compiled by the original thewidget* w1=Newwidgets (); +widget* w3= (widget*)operator New(sizeof(widgets)); - //This call was not compiled by the original $ New(W3) widget (); $ return 0; -}
Note that this side requires the using Globalscopenew::operator new in the subclass; That is, the operator new of the base class is visible in the subclass.
In this way, all forms of the new operator call can be compiled.
C + + new/new operator, operator new, placement new