The new Operator/delete operator is the new and delete operator, and operator New/operator Delete is a function.
New operator
(1) Call operator new to allocate enough space and call the constructor of the related object
(2) can not be overloaded
operator NEW
(1) Allocate only the required space and do not invoke the constructor of the related object. When the required allocated space is not met, the
-> If there is a new_handler, call New_handler, otherwise
-> If there is no requirement not to throw an exception (expressed as a nothrow parameter), then the bad_alloc exception is executed, otherwise
-> return 0
(2) can be overloaded
(3) When overloaded, the return type must be declared as void*
(4) When overloaded, the first parameter type must be the size (in bytes) of the expression requirement allocation space, and the type is size_t
(5) When overloaded, can take other parameters
Delete is similar to the delete operator.
Copy Code code as follows:
#include <iostream>
#include <string>
using namespace Std;
Class X
{
Public
X () {cout<< "constructor of X" <<endl;}
~x () {cout<< "destructor of X" <<ENDL;}
void* operator new (size_t size,string str)
{
cout<< "operator new size" <<size<< "with string" <<str<<endl;
Return:: operator new (size);
}
void operator Delete (void* pointee)
{
cout<< "operator Delete" <<endl;
:: operator Delete (pointee);
}
Private
int num;
}
int main ()
{
X *px=new ("A new Class") x;
Delete px;
return 0;
}
x* px = new X; The new in the line code is new operator, which calls the operator new in class X, allocates space for objects of that class, and then calls the constructor of the current instance.
Delete px; The delete in the line code is the delete operator, which calls the destructor of the instance, and then calls the operator delete in class X to free up the space occupied by the instance.
The behavior of the new operator and delete operator cannot and should not be changed, which is the commitment of the C + + standard. The operator new and the malloc in the operator delete and C languages correspond to free, which is responsible for allocating and releasing space only. However, the space allocated using operator new must be freed using the operator delete, not free, because they are registered differently for memory usage. The reverse is also the same. You can overload operator new and operator Delete to achieve different requirements for memory management, but you cannot overload the new operator or delete operator to change their behavior.
Why is it necessary to write your own operator new and operator delete?
The answer is usually: for efficiency. The default operator new and operator Delete are very versatile, and this flexibility makes it possible to further improve its performance in certain situations. This is especially true in applications that need to dynamically allocate large but small objects. Specific reference to the "effective C + +" in chapter II memory management.
The meaning of placement new
Placement new is a standard, global version of the overloaded operator new that cannot be replaced by a custom version (unlike the normal version of operator new AND operator delete).
void *operator new (size_t, void * p) throw () {return p;}
The execution of placement new ignores the size_t parameter and returns only the second argument. The result is that the user is allowed to put an object in a specific place and achieve the effect of calling the constructor. Unlike other ordinary new, it has another argument in parentheses. Like what:
Widget * p = new Widget; Ordinary New
PI = new (ptr) int; PI = new (ptr) int; Placement NEW
The parameter ptr in parentheses is a pointer to a memory buffer in which placement new assigns an object to the buffer. The return value of placement new is the address of the constructed object (such as the passing parameter in parentheses). Placement new is primarily useful in applications that are very demanding in time, because the time that these programs are assigned is determined, the programs that run long hours without interruption, and the execution of a garbage collector (garbage collector).
New, operator new and placement new difference
(1) NEW: cannot be overloaded, its behavior is always the same. It first calls operator new to allocate memory, and then calls the constructor to initialize that memory.
The execution process of the new operator:
1. Call operator new to allocate memory;
2. Call constructor to generate class object;
3. Return the corresponding pointer.
(2) operator NEW: to implement different memory allocation behavior, you should overload operator new instead of new.
operator new, like Operator +, can be overloaded. If there is no overload operator new in the class, then the call is global:: operator new to complete the heap allocation. Similarly, operator new[], operator delete, operator delete[] can also be overloaded.
(3) Placement NEW: just a version of operator new overload. It does not allocate memory, but simply returns a pointer to a segment of memory that has been allocated. Therefore, you cannot delete it, but you need to invoke the destructor of the object.
If you want to create an object in the allocated memory, it won't work when you use new. In other words, placement new allows you to construct an object in an already allocated memory (stack or heap). The void* p in the prototype is actually the first address that points to an already allocated memory buffer.
Placement the reason for the new existence
1. Solve the problem of buffer with placement new
problem Description: when array buffering is allocated with new, execution is inefficient because the default constructor is invoked. A compile-time error occurs if there is no default constructor. If you want to create an object on a pre-configured memory, it won't work with the default new operator. To solve this problem, you can use placement new constructs. It allows you to construct a new object into the preconfigured memory.
2. Increase the time and space efficiency problem
allocating memory using the new operator requires looking for a large enough amount of space in the heap, which is obviously slow, and there may be an exception (not enough space) to allocate memory. Placement new can solve this problem. We construct objects in a prepared memory buffer, do not need to find memory, memory allocation time is constant, and there is no out-of-memory exception in the middle of the program run. Therefore, placement new is ideal for applications that have high time requirements and do not want to be interrupted for long periods of time.
Placement new Use steps
In many cases, the use of placement new is different from other ordinary new. The steps to use it are provided here.
First step cache advance allocation
There are three different ways:
1. To ensure that the memory alignment (memory queue) of the buffer used by placement new is properly prepared, use the normal new to allocate it: allocate on the heap
Class Task;
char * buff = new [sizeof (Task)]; Allocating memory
(Note that auto or static memory is not all aligned correctly for each object type, so you won't be able to use them with placement new.) )
2. Distribute on the stack
Class Task;
Char buf[n*sizeof (Task)]; Allocating memory
3. Another way is to use the address directly. (Must be a meaningful address)
void* buf = reinterpret_cast<void*> (0xf00f);
Step Two: Assignment of objects
Call placement new to construct an object in the cache that has just been allocated.
Task *ptask = new (BUF) task
Step Three: Use
Use assigned objects in the normal way:
Ptask->memberfunction ();
Ptask-> member;
//...
Fourth step: The Deconstruction of objects
Once you have finished using this object, you must call its destructor to destroy it. Call the destructor in the following way:
Ptask->~task (); Calling an external destructor
Step Fifth: Release
You can reuse the cache and assign it a new object (Repeat step 2,3,4) If you do not intend to use the cache again, you can release it like this: delete [] buf;
Skipping any step can lead to runtime crashes, memory leaks, and other unexpected scenarios. If you really need to use placement new, please follow these steps carefully.
Copy Code code as follows:
#include <iostream>
using namespace std;
Class X
{
Public:
x () {cout<< "constructor of X" <<endl;}
~x () {cout<< "destructor of X" <<ENDL;}
void Setnum (int n)
{
num = N
}
int getnum ()
{
return num ;
}
Private:
int num;
};
Int main ()
{
char* buf = new char[sizeof (X)];
x *px = new (BUF) x;
Px->setnum (10);
cout<<px->getnum () <<endl;
px->~x ();
Delete []buf;
return 0;
}