Wednesday, November 22, 2006

operator new - new operator

At first shot this two entities can appear to be the same; however they are not.
Let see what they are, what you can change and the safe rules to handle them.

First of all let see what happens when you write something like:

C * pC = new C;
  • Enough memory is allocated to contain the object requested
  • The constructor of C is called to initialize the object the lays in the memory allocated
This described is the new operator behave and you can not change the way he acts.

The first point in the sequence above is the only think you can change, the way the memory is allocated, the new operator uses for this task what is called: operator new.

So the pseudo code for C * pC = new C; could be:
  1. Call operator new
  2. Construct an object of the type request at the location returned from previous step
The operator new signature is something like this:

void * operator new(size_t);

so if you want change the way the new operator allocates the memory for your type then you need to rewrite the operator new.
As you already know when you specify a name in a scope ( for example a method name in a class ) this will hide the same name in the scopes that are containing your actual ( the base class scope for example ). So rewriting your operator new what you do is to hide the other forms of operator new. For instance these forms are:
  1. void * operator new(std::size_t, std::nothrow_t) throw();
  2. void * operator new(std::size_t, void *);
the former is the nothrow new the latter is the in place new. Actualy you can break more than this if you define your own operator new, something like:
  • void * operator new(std::size_t, T);
remember in this case that first argument of operator new shall be always std::size_t, in this case you will hide not only the "less common" operator new version but also the plain new one. I quoted less common because in reality the STL does heavy usage of in place new.

No comments: