Overloading operators new and delete
Before studying this topic, it is recommended to familiarize yourself with the following topic:
Contents
- 1. When do you need to overload the operators new and delete?
- 2. What methods of overload can be performed on the new and delete operators?
- 3. The general form of operator overloading new
- 4. The general form of operator overload delete
- 5. For which types (classes) can the overloaded operators new and delete be used?
- 6. Example of overloading the new and delete operators inside a class for single objects
- 7. Example of global overloading of new and delete operators for single objects
- 8. An example of overloading the new and delete operators within the class boundaries in the case of memory allocation for an array
- 9. Example of global overloading of the new[] and delete[] operators for arrays
- Related topics
Search other websites:
1. When do you need to overload the operators new and delete?
The new operator must be reloaded in cases where memory is allocated in non-standard way. Accordingly, the delete operator should free this memory in a non-standard way. As a rule, if the operator new is overloaded in a class, then the operator delete is also overloaded in this class.
⇑
2. What methods of overload can be performed on the new and delete operators?
The new and delete operators can be overloaded in various ways. These methods differ in the declaration of an operator function. The following are all valid methods for overloading:
- overloading the new and delete operators with an operator function that is implemented within the class. This is a way to overload new and delete for a particular class. When calling new and delete for this class, overloaded operator functions will be called that allocate/free memory in a specific way. When calling the new and delete operators for other classes, the global operators new and delete are used;
- global overload of the operators new and delete. In this case, the new and delete operators are overloaded for built-in types (float, int, etc.).
⇑
3. The general form of operator overloading new
The general form of overloading the new operator is as follows:
return_type * operator new(size_t size) { // Memory allocation // ... }
here
- return_type is a type (class) to which the operator function returns a pointer for which memory is allocated by a special (non-standard method);
- size – size of memory that is allocated for return_type type. The number of bytes allocated memory does not have to match the size, since the body of the operator function memory you can allocate special.
⇑
4. The general form of operator overload delete
The general form of operator overload delete is as follows:
void operator delete(void * pointer) { // freeing the memory pointed to by the pointer pointer // ... }
here pointer – a pointer to the memory area that was previously allocated by the operator new.
⇑
5. For which types (classes) can the overloaded operators new and delete be used?
If the program overloads the operators new and delete, then there are two types of these operators:
- overloaded operators new and delete. These overloaded operators are applied to a particular class, which has operator new() and operator delete();
- global operators new and delete (not overloaded). These operators are used for classes that do not contain operator functions that overload the new and delete operators.
For each class, the compiler determines which variant of the new and delete operators to choose: global or for a specific class.
⇑
6. Example of overloading the new and delete operators inside a class for single objects
The example declares the class Complex, which implements a complex number. The class contains:
- internal variables real, imag, which correspond to the real and imaginary parts of the complex number;
- class constructor;
- access methods Get(), Set();
- overloaded operator functions operator new(), operator delete() which overload respectively the operators new and delete. These functions are used strictly for the Complex class. The implementation of the Complex class and the main() function, which demonstrates the overloading of the new and delete operators, is as follows:
#include "stdafx.h" #include <iostream> #include <cstdlib> #include <new> using namespace std; // class containing overloaded operators new and delete class Complex { private: double real; double imag; public: // constructor Complex(double _real, double _imag) { real = _real; imag = _imag; } // access methods void Get(double * r, double * i) { *r = real; *i = imag; return; } void Set(double r, double i) { real = r; imag = i; } // overloaded operator new, // allocates memory of a given size void * operator new(size_t size) { void * ptr; cout<<"Attempt to allocate memory \n"; ptr = malloc(size); // Attempt to allocate memory if (!ptr) // if no memory is allocated, then generate an exception { bad_alloc ba; cout<<"Memory allocation error.\n"; throw ba; } else { // cout<<"Memory is allocated successfully!\n"; return ptr; } } // It frees the memory allocated to the overloaded // operator function operator new() void operator delete(void * ptr) { cout<<"Free the memory allocated by the delete operator.\n"; free(ptr); } }; int _tmain(int argc, _TCHAR* argv[]) { // demonstration of the use of the new and delete operators in the Complex class Complex * p1; // declare a pointer to the Complex try { // invoke the operator function operator new() p1 = new Complex(5,6); // allocate memory } catch (bad_alloc error) { return 1; // exit the program with a return code 1 } // free up memory // invoke the operator function operator delete() delete p1; return 0; }
As a result of executing the above code, the following result will be displayed:
Attempt to allocate memory Memory is allocated successfully! Free the memory allocated by the delete operator.
⇑
7. Example of global overloading of new and delete operators for single objects
The new and delete operators can be globally overloaded. In this case, the use of the global overloaded operators new and delete can be used for any type. The following is an example of a global overload of the new and delete operators.
#include "stdafx.h" #include <iostream> #include <cstdlib> using namespace std; // class that contains the overloaded operators new and delete class Complex { private: double real; double imag; public: // constructor Complex(double _real, double _imag) { real = _real; imag = _imag; } // access methods void Get(double * r, double * i) { *r = real; *i = imag; return; } void Set(double r, double i) { real = r; imag = i; } }; // global operator new void * operator new(size_t size) { void * ptr; cout<<"Global operator new"<<::endl; cout<<"1. Attempting to allocate memory with the malloc function()\n"; ptr = malloc(size); // attempt to allocate memory if (!ptr) // if memory is not allocated, then an exception is thrown { bad_alloc ba; cout<<"2. Memory allocation error.\n"; throw ba; } else { cout<<"3. Memory allocated successfully by global operator new\n"; return ptr; } } // global operator delete void operator delete(void * ptr) { cout<<"4. Global operator delete.\n"; free(ptr); } int _tmain(int argc, _TCHAR* argv[]) { // demonstration of the use of the global operators new and delete Complex * p; // declare a pointer to the Complex int * p; // pointer to int try { // invoke the operator function operator new() p = new Complex(5,6); // allocate memory } catch (bad_alloc error) { cout<<"Error allocating memory for object p"<<::endl; return 1; // exit the program with code 1 } // free up memory // invoke the global operator delete() delete pC; try { // call the overloaded version of the operator new cout<<"Attempt to allocate memory for object pI"<<::endl; pI = new int; } catch (bad_alloc error) { cout<<"Error allocating memory for pI "<<::endl; return 2; // exit the program with a return code 2 } delete pI; return 0; }
As a result of executing the above code, the following result will be displayed:
Global operator new 1. Attempting to allocate memory with the malloc function() 3. Memory allocated successfully by global operator new 4. Global operator delete. Attempt to allocate memory for object pI 1. Attempting to allocate memory with the malloc function() 3. Memory allocated successfully by global operator new 4. Global operator delete.
As can be seen from the result, the global operators new and delete work both for base types and for classes.
⇑
8. An example of overloading the new and delete operators within the class boundaries in the case of memory allocation for an array
An example of overloading the operators new and delete for an array of objects of type Point is given. The Point class defines a point on the coordinate plane and contains the following declarations:
- variables x, y which are the coordinates of a point;
- constructors;
- access methods Get(), Set();
- the operator functions operator new() and operator delete(), implementing the allocation/release of memory for single objects of type Point;
- operator functions operator new[]() and operator delete[](), which implement memory allocation/release for arrays of objects of type Point.
The program code that implements the Point class is as follows:
#include "stdafx.h" #include <iostream> #include <cstdlib> #include <new> using namespace std; class Point { private: double x, y; public: // constructors Point() { x = y = 0.0; } Point(double _x, double _y) { x = _x; y = _y; } // access methods void Get(double * _x, double * _y) { *_x = x; *_y = y; } void Set(double _x, double _y) { x = _x; y = _y; } // overloaded operator new for single object of class Point void * operator new(size_t size) { void * ptr; ptr = malloc(size); if (!ptr) { bad_alloc error; throw error; } return ptr; } // overloaded delete statement for a single object of class Point void operator delete(void * ptr) { cout<<"Memory freeing using delete operator"<<::endl; free(ptr); } // перегруженный оператор new для массива объектов типа Point void * operator new[](size_t size) { void * ptr; cout<<"The use of an overloaded operator new[]."<<::endl; ptr = malloc(size); if (!ptr) { bad_alloc error; throw error; } return ptr; } // overloaded delete operator for an array of objects of type Point void operator delete[](void * ptr) { cout <<"Delete array from memory by operator delete[]"<<::endl; free(ptr); } }; int _tmain(int argc, _TCHAR* argv[]) { // overloading the new and delete operators for arrays of objects Point * p1; try { // invoke the overloaded operator function operator new[]() // of class Point p1 = new Point[5](); } catch (bad_alloc error) { cout<<"Error allocating memory for object p1."<<::endl; return 1; } delete[] p1; return 0; }
As a result of executing the above code, the following result will be displayed.
The use of an overloaded operator new[]. Delete array from memory by operator delete[]
Important: in order to overload the operators new and delete for arrays, it is not necessary to overload these operators for single objects.
⇑
9. Example of global overloading of the new[] and delete[] operators for arrays
Below is an example of global overloading of the operators new[] and delete[] for arrays of class Point
#include "stdafx.h" #include <iostream> #include <cstdlib> using namespace std; class Point { private: double x, y; public: // constructors Point() { x = y = 0.0; } Point(double _x, double _y) { x = _x; y = _y; } // access methods void Get(double * _x, double * _y) { *_x = x; *_y = y; } void Set(double _x, double _y) { x = _x; y = _y; } }; // overloaded operator new for single object of class Point void * operator new(size_t size) { void * ptr; ptr = malloc(size); if (!ptr) { bad_alloc error; throw error; } return ptr; } // overloaded operator delete for a single object of class Point void operator delete(void * ptr) { cout<<"Releace memory using delete operator"<<::endl; free(ptr); } // overloaded operator new for an array of objects of type Point void * operator new[](size_t size) { void * ptr; cout<<"Using the overloaded operator new[]."<<::endl; ptr = malloc(size); if (!ptr) { bad_alloc error; throw error; } return ptr; } // overloaded delete operator for an array of objects of type Point void operator delete[](void * ptr) { cout <<"Releace array from memory by operator delete[]"<<::endl; free(ptr); } int _tmain(int argc, _TCHAR* argv[]) { // global overloading of the new and delete operators for arrays of objects Point * p1; // pointer to class Point float * p2; // pointer to float try { // invoke the overloaded global operator function operator new[]() // of class Point p1 = new Point[5](); } catch (bad_alloc error) { cout<<"Error allocating memory for object p1."<<::endl; return 1; } delete[] p1; // invoke the global operator function operator new[]() for the base type float try { p2 = new float[10]; // function call } catch (bad_alloc error) { cout<<"Error allocating memory for object p2."<<::endl; return 2; } delete[] p2; return 0; }
As a result of executing the above code, the following result will be displayed:
Using the overloaded operator new[]. Releace array from memory by operator delete[]
As can be seen from the result, the overloaded global operator functions operator new[] and operator delete[] for arrays work in the same way as with the base types (float) and with the class types (Point).
⇑
Related topics
- Operator overloading in C++. Operator function. Keyword operator. Overload of basic arithmetic operators +, –, *, /. Examples of the implementation of built-in operator functions
- “Friendly” operator functions: differences, implementation. Overload of operators +, –, *, / with the help of friendly operator functions