new and deletenew() must have a return type of void* and take a first parameter of type size_t.
class Screen {
public:
void *operator new( size_t );
};
new expression creates an object of class type, the compiler looks to see if the class has a member operator new(). If it has, this operator is selected to allocate the memory for the class object; otherwise, the global operator new() is called.new() through the use of the global scope resolution operator. For example:
Screen *ps = ::operator new Screen
invokes the global operator new() even if class Screen defines operator new() as a member.
delete() must have a void return type and a first parameter of type void*.
class Screen {
public:
void operator delete(void*);
};
delete expression is a pointer to an object of class type, the compiler looks to see if the class has a member operator delete(). If it has, this operator is selected to deallocate the memory for the class object; otherwise, the global operator delete() is called.delete() by using the global scope resolution operator. For example: ::operator delete ps; invokes the operator delete() defined in global scope even if class Screen defines operator delete() as a member.delete() used should match the operator new() that is used to allocate the storage. For example, if ps refers to storage that was allocated with a new expression invoking the global operator new(), then the delete expression should also invoke the global operator delete().delete() defined for a class type and called by a delete expression may have two parameters instead of one. The first parameter must still be of type void*. The second parameter must be of the predefined type size_t.
class Screen {
public:
// replaces:
void operator delete( void *, size_t );
};
If present, the additional parameter is initialized automatically by the compiler with the size in bytes of the object addressed by the first parameter.
static is optional for these functions: whether used or not, the allocation function is a static member function. Why? operator new/delete are called before/after any object is created. So there’s no this pointer — because there’s no object yet!new() (no matter default new or not), such as Screen *ptr = new Screen( 10, 20 ); is equivalent to the following two-statement sequence:
// Pseudo C++ code
ptr = Screen::operator new( sizeof( Screen ) );
Screen::Screen( ptr, 10, 20 );
new[] and delete[]new[] is a built-in or user-defined function used to allocate a block of memory large enough to hold an array of objects. For example:
Screen* ps = new Screen[5];
new[]() must have a return type of void* and take a first parameter of type size_t.
class Screen {
void* operator new[]( size_t );
};
new expression creates an array of objects of class type, the compiler looks to see if the class has a member operator new[](). If it does, this operator is selected to allocate the memory for the array; otherwise, the global operator new[]() is called.size_t parameter is initialized automatically with a value that represents the size of the storage required to store an array of ten Screen objects in bytes.new[](), the programmer can invoke the global operator new[]() to create an array of Screen objects through the use of the global scope resolution operator.delete[]() must have a void return type and a first parameter of type void*.
class Screen {
void operator delete[]( void* );
};
delete[] ps;
delete expression is a pointer to class type, the compiler looks to see if the class has a member operator delete[](). If it does, this operator is selected to deallocate the memory for the array; otherwise, the global operator delete[]() is called.void* parameter is initialized automatically with a value that represents the beginning of the storage in which the array is stored.delete[](), the programmer can invoke the global operator delete[]() selectively by using the global scope resolution operator. For example, ::operator delete[] ps; invokes the operator delete[]() defined in global scope.new expression that creates an array first calls the class operator new[]() to allocate the storage and then calls the default constructor to initialize iteratively every element of the array.new expression is an error.new expression for arrays.delete[]() to deallocate the storage.delete[]() for a class may also have two parameters instead of one, the second parameter being of the predefined type size_t. For example:
class Screen {
public:
void operator delete[]( void*, size_t );
};
If present, the additional parameter is initialized automatically by the compiler with the size in bytes of the storage required to store the array.
new() and delete()new() must always be a parameter of type size_t. The additional parameters are initialized with the placement arguments specified in a new expression.
class Screen {
void *operator new( size_t, Screen* );
};
Screen* start = new Screen;
Screen* ps = new(start) Screen;
delete(). However, such an operator is never invoked from a delete expression. An overloaded operator delete() is only called implicitly by the implementation if the constructor called by a new expression (yes, this is not a typo, we really mean a new expression) throws an exception.new expression
Screen *ps = new ( start ) Screen;
are as follows:
a. It calls the class operator new(size_t, Screen*).
b. It then calls the default constructor for class Screen to initialize the object.
c. It then initializes ps with the address of the Screen object.
delete() with parameters with types that match the parameter types of operator new(), the implementation automatically calls this operator delete() to deallocate the storage. For example,
Screen *ps = new (start) Screen;
If the default constructor for class Screen exits by throwing an exception, the implementation looks for an operator delete() in the scope of class Screen. For an operator delete() to be considered, it must have parameters with types that match those of the operator new() called. The implementation looks in class Screen for an operator delete() of the following form:
void operator delete( void*, Screen* );
delete() that matches a specific operator new(), depending on whether the operator new() allocates storage or whether it reuses storage already allocated. If it allocates storage, then a placement operator delete() should be provided to deallocate the memory in case the constructor throws an exception when called from a new expression. If the placement operator new() does not allocate storage, then there is no need to provide a matching operator delete() to deallocate the memory.#include <iostream>
#include <string>
#include <cstdlib>
class Screen {
public:
Screen(int x, int y) : m_x(x), m_y(y){}
Screen() : m_x(-1), m_y(-1){}
// Single object
void* operator new( size_t );
// If delete(void*) and delete(void*,size_t) are present,
// compiler calls delete(void*)
void operator delete( void* );
void operator delete( void*, size_t );
// Array objects
void* operator new[]( size_t );
void operator delete[]( void* );
void operator delete[]( void*, size_t );
// Placement operators
void* operator new( size_t, void* );
void operator delete( void*, void* );
void* operator new[]( size_t, void* );
void operator delete[]( void*, void* );
void showPosition();
private:
int m_x;
int m_y;
};
void* Screen::operator new( size_t size )
{
std::cout<< "Overloading new operator with size: " << size << " bytes\n";
//void* ptr = ::operator new(size);
void* ptr = malloc(size);
return ptr;
}
void Screen::operator delete( void* ptr )
{
std::cout<< "Overloading delete operator with unknown size\n";
free(ptr);
}
void Screen::operator delete( void* ptr, size_t size )
{
std::cout<< "Overloading delete operator with size: " << size << " bytes\n";
free(ptr);
}
void* Screen::operator new[]( size_t size )
{
std::cout<< "Overloading new[] operator with size: " << size << " bytes\n";
void* ptr = malloc(size);
return ptr;
}
void Screen::operator delete[]( void* ptr )
{
std::cout<< "Overloading delete[] operator with unknown size\n";
free(ptr);
}
void Screen::operator delete[]( void* ptr, size_t size )
{
std::cout<< "Overloading delete[] operator with size: " << size << " bytes\n";
free(ptr);
}
void* Screen::operator new( size_t size, void* ptr)
{
std::cout << "Placement new overloaded: using custom memory\n";
return ptr;
}
void Screen::operator delete( void*, void* ptr)
{
std::cout << "Placement new overloaded: using custom memory\n";
free(ptr);
}
void* Screen::operator new[]( size_t size, void* ptr)
{
std::cout << "Placement new overloaded: using custom memory\n";
return ptr;
}
void Screen::operator delete[]( void*, void* ptr)
{
std::cout << "Placement new overloaded: using custom memory\n";
free(ptr);
}
void Screen::showPosition()
{
std::cout << "m_x=" << this->m_x << ", m_y=" << this->m_y << "\n";
}
int main(){
// Allocate single object
Screen *s = new Screen(1, 3);
s->showPosition();
delete s;
// Allocate object array
Screen *as = new Screen[10];
for (int i=0;i<10;i++){
as[i].showPosition();
}
delete[] as;
// Place single object
char* start1 = new char [sizeof(Screen)];
Screen* ps = new(start1) Screen;
ps->showPosition();
delete[] start1;
// Place object array
char* start2 = new char [sizeof(Screen)*10];
Screen* psa = new(start2) Screen[10];
for (int i=0;i<10;i++){
psa[i].showPosition();
}
delete[] start2;
return 0;
}