Professional C__ - Marc Gregoire [328]
void operator delete[](void* ptr) noexcept;
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
void operator delete(void* ptr, const std::nothrow_t&) noexcept;
void* operator new[](std::size_t size, const std::nothrow_t&) noexcept;
void operator delete[](void* ptr, const std::nothrow_t&) noexcept;
};
Code snippet from Memory\MemoryDemo.h
Here are simple implementations of these operators that pass the argument through to calls to the global versions of the operators. Note that nothrow is actually a variable of type nothrow_t:
void* MemoryDemo::operator new(size_t size)
{
cout << "operator new" << endl;
return ::operator new(size);
}
void MemoryDemo::operator delete(void* ptr) noexcept
{
cout << "operator delete" << endl;
::operator delete(ptr);
}
void* MemoryDemo::operator new[](size_t size)
{
cout << "operator new[]" << endl;
return ::operator new[](size);
}
void MemoryDemo::operator delete[](void* ptr) noexcept
{
cout << "operator delete[]" << endl;
::operator delete[](ptr);
}
void* MemoryDemo::operator new(size_t size, const nothrow_t&) noexcept
{
cout << "operator new nothrow" << endl;
return ::operator new(size, nothrow);
}
void MemoryDemo::operator delete(void* ptr, const nothrow_t&) noexcept
{
cout << "operator delete nothrow" << endl;
::operator delete[](ptr, nothrow);
}
void* MemoryDemo::operator new[](size_t size, const nothrow_t&) noexcept
{
cout << "operator new[] nothrow" << endl;
return ::operator new[](size, nothrow);
}
void MemoryDemo::operator delete[](void* ptr, const nothrow_t&) noexcept
{
cout << "operator delete[] nothrow" << endl;
::operator delete[](ptr, nothrow);
}
Code snippet from Memory\MemoryDemo.cpp
Here is some code that allocates and frees objects of this class in several ways:
MemoryDemo* mem = new MemoryDemo();
delete mem;
mem = new MemoryDemo[10];
delete [] mem;
mem = new (nothrow) MemoryDemo();
delete mem;
mem = new (nothrow) MemoryDemo[10];
delete [] mem;
Code snippet from Memory\MemoryDemoTest.cpp
Here is the output from running the program:
operator new
operator delete
operator new[]
operator delete[]
operator new nothrow
operator delete
operator new[] nothrow
operator delete[]
These implementations of operator new and operator delete are obviously trivial and not particularly useful. They are intended only to give you an idea of the syntax in case you ever want to implement nontrivial versions of them.
Whenever you overload operator new, overload the corresponding form of operator delete. Otherwise, memory will be allocated as you specify but freed according to the built-in semantics, which may not be compatible.
It might seem overkill to overload all of the various forms of operator new. However, it’s generally a good idea to do so in order to prevent inconsistencies in the memory allocations. If you don’t want to provide implementations, you can declare the function as protected or private in order to prevent anyone from using it.
Overload all forms of operator new, or provide private declarations without implementations for the forms that you don’t want to get used.
Overloading operator new and operator delete with Extra Parameters
In addition to overloading the standard forms of operator new, you can write your own versions with extra parameters. For example, here is the MemoryDemo class showing an additional operator new and operator delete with an extra integer parameter:
#include class MemoryDemo { public: // Omitted for brevity void* operator new(std::size_t size, int extra); void operator delete(void* ptr, int extra) noexcept; }; Code snippet from Memory\MemoryDemo.h The implementation is as follows: void* MemoryDemo::operator new(size_t size, int extra) { cout << "operator new with extra int arg" << endl; return ::operator new(size); } void MemoryDemo::operator delete(void* ptr, int extra) noexcept { cout << "operator delete with extra int arg" << endl; return ::operator delete(ptr); } Code snippet from Memory\MemoryDemo.cpp When you