Overloading operator new(size_t)

If the operator new is overloaded, it must have a void * return type, and at least an argument of type size_t. The size_t
type is defined in stddef.h, which must therefore be included when the operator new is overloaded.
It is also possible to define multiple versions of the operator new, as long as each version has its own unique set of
arguments. The global new operator can still be used, through the ::-operator. If a class X overloads the operator new,
then the system-provided operator new is activated by

X *x = ::new X();

Furthermore, the new [] construction will always use the default operator new.
An example of the overloaded operator new for the class X is the following:

#include <stddef.h>
void *X::operator new(size_t sizeofX)
{
  void *p = new char[sizeofX];
  return (memset(p, 0, sizeof(X)));
}

Now, what happens when the operator new is defined for the class X, assuming that class is defined as follows (For
the sake of simplicity we have violated the principle of encapsulation here. The principle of encapsulation, however,
is immaterial to the discussion of the workings of the operator new.):

class X
{
public:
  void *operator new(size_t sizeofX);
  int x, y, z;
};

Next, consider the following program fragment:

#include "X.h" // class X interface etc.
int main()
{
  X *x = new X();
  cout << x->x << ", " << x->y << ", "<< x->z << endl;
  return (0);
}

This small program produces the following output:
0, 0, 0
Our little program performed the following actions:

  • First, operator new was called, which allocated and initialized a block of memory, the size of an X object.
  • Next, a pointer to this block of memory was passed to the (default) X() constructor. Since no constructor was

defined, the constructor itself didn’t do anything at all.
Due to the initialization of the block of memory by the new operator the allocated X object was already initialized to
zeros when the constructor was called.
Non-static object member functions are passed a (hidden) pointer to the object on which they should operate. This
hidden pointer becomes the this pointer inside the memberfunction. This procedure is also followed by the
constructor. In the following fragments of pseudo C++ the pointer is made visible. In the first part an X object is
declared directly, in the second part of the example the (overloaded) operator new is used:

X::X(&x); // x's address is passed to the constructor
// the compiler made 'x' available
void // ask new to allocate the memory for an X
*ptr = X::operator new();
X::X(ptr); // and let the constructor operate on the
// memory returned by 'operator new'

Notice that in the pseudo C++ fragment the member functions were treated as static functions of the class X. Actually,
the operator new() operator is a static functions of its class: it cannot reach data members of its object, since it’s
normally the task of the operator new() to create room for that object first. It can do that by allocating enough
memory, and by initializing the area as required. Next, the memory is passed over to the constructor (as the this
pointer) for further processing. The fact that an overloaded operator new is in fact a static function, not requiring an
object of its class can be illustrated in the following (discouraged in normal situations !) program fragment, which can
be compiled without problems (assume class X has been defined and is available as before):

int main()
{
  X x;
  X::operator new(sizeof x);
  return (0);
}

The call to X::operator new() returns a void * to an initialized block of memory, the size of an X object.
The operator new can have multiple parameters. The first parameter again is the size_t parameter, other parameters
must be passed during the call to the operator new. For example:

class X
{
public:
  void *operator new(size_t p1, unsigned p2);
  void *operator new(size_t p1, char const *fmt, ...);
};
int main()
{
  X *object1 = new(12) X(), *object2 = new("%d %d", 12, 13) X(),
     *object3 = new("%d", 12) X();
  return (0);
}

The object (object1) is a pointer to an X object for which the memory has been allocated by the call to the first
overloaded operator new, followed by the call of the constructor X() for that block of memory. The object (object2) is
a pointer to an X object for which the memory has been allocated by the call to the second overloaded operator new,
followed again by a call of the constructor X() for its block of memory. Notice that object3 also uses the second
overloaded operator new(): that overloaded operator accepts a variable number of arguments, the first of which is a
char const *.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Add to favorites
  • LinkedIn
  • Propeller
  • Reddit
  • StumbleUpon
  • Technorati
  • Twitter
  • Yahoo! Bookmarks

Related posts:

  1. Overloading operator delete(void *)
  2. Overloading operator[]()
  3. Overloading ++ and –
  4. Why sizeof is an operator, not a function?
  5. Differences between new, malloc; delete, free

Tags:

Leave a Reply