Nimmi Srivastav
2004-01-31 23:39:26 UTC
There's a rather nondescript book called "Using Borland C++" by Lee
and Mark Atkinson (Que Corporation) which presents an excellent
discussion of overloaded new and delete operators.
I am presenting below a summary of what I have gathered. I would
appreciate if someone could point out to something that is specific to
Borland C++ and is not supported by the ANSI standard. I am also
concerned that some of the information may be outdated since the book
is quite old (1991 edition).
1) We cannot use the array size declarator with a class-specific
user-defined new function. Arrays of objects are always allocated
with the global new.
2) Overloaded new and delete operators should be provided in pairs.
3) Class-specific new and delete functions are always static member
functions, even though they are not explicitly declared with the
static storage class specifier.
4) A class can have many overloaded new functions ---- the correct
function is selected through best-fit signature matching, as for any
other overloaded function.
5) The first argument of each overloaded new operator is a size_t
object size argument. However, this argument is implicit and is not
provided when the overloaded new operator is invoked.
6) A class can have only one overloaded delete operator.
7) The overloaded delete operator is invoked after the last line of
the destructor has been executed.
// ~~~~~~~ Code snippet begin ~~~~~~~
#include <iostream.h>
/////////////////////////////////////////////////////////////////
class X
{
int a, b, c;
public:
~X() { cout << "Inside destructor of class X" << endl; }
// You are allowed to declare only one delete function
void operator delete( void* ptr);
// You can overload new however you want, as long as the first
// argument is always a size_t object-size argument
//
// !!!!! Important note: The size_t parameter is
// implicit. Do not write it directly into
// the function call. !!!!!
void* operator new(size_t size);
void* operator new(size_t size, void* ptr);
void* operator new(size_t size, int flag);
};
/////////////////////////////////////////////////////////////////
void* X::operator new(size_t size)
{
void* ptr;
cout << "Standard class new called.\r\n";
ptr = (void*) ::new unsigned char[size];
return ptr;
}
/////////////////////////////////////////////////////////////////
void* X::operator new(size_t size, void* ptr)
{
size = size;
cout << "Placement class new called.\r\n";
return ptr;
}
/////////////////////////////////////////////////////////////////
void* X::operator new(size_t size, int flag)
{
void* ptr;
cout << "Overloaded class new called. ";
cout << "Flag was " << flag << ".\r\n";
ptr = (void*) ::new unsigned char[size];
return ptr;
}
/////////////////////////////////////////////////////////////////
void X::operator delete( void* ptr)
{
cout << "Class delete called.\r\n";
free(ptr);
}
/////////////////////////////////////////////////////////////////
int main()
{
X* objl = new X;
// Remember the size_t parameter is implicit
// The standard class new is called
// void* X::operator new(size_t size)
delete objl;
X* obj2;
void* buf = (void*) ::new unsigned char[sizeof(X)];
obj2 = new(buf) X;
// Remember the size_t parameter is implicit
// The placement class new called
// void* X::operator new(size_t size, void* ptr)
free(buf);
X* obj3 = new(64) X;
// Remember the size_t parameter is implicit
// The overloaded class new called
// void* X::operator new(size_t size, int flag)
delete obj3;
}
// ~~~~~~~ Code snippet end ~~~~~~~
Thanks,
Nimmi
and Mark Atkinson (Que Corporation) which presents an excellent
discussion of overloaded new and delete operators.
I am presenting below a summary of what I have gathered. I would
appreciate if someone could point out to something that is specific to
Borland C++ and is not supported by the ANSI standard. I am also
concerned that some of the information may be outdated since the book
is quite old (1991 edition).
1) We cannot use the array size declarator with a class-specific
user-defined new function. Arrays of objects are always allocated
with the global new.
2) Overloaded new and delete operators should be provided in pairs.
3) Class-specific new and delete functions are always static member
functions, even though they are not explicitly declared with the
static storage class specifier.
4) A class can have many overloaded new functions ---- the correct
function is selected through best-fit signature matching, as for any
other overloaded function.
5) The first argument of each overloaded new operator is a size_t
object size argument. However, this argument is implicit and is not
provided when the overloaded new operator is invoked.
6) A class can have only one overloaded delete operator.
7) The overloaded delete operator is invoked after the last line of
the destructor has been executed.
// ~~~~~~~ Code snippet begin ~~~~~~~
#include <iostream.h>
/////////////////////////////////////////////////////////////////
class X
{
int a, b, c;
public:
~X() { cout << "Inside destructor of class X" << endl; }
// You are allowed to declare only one delete function
void operator delete( void* ptr);
// You can overload new however you want, as long as the first
// argument is always a size_t object-size argument
//
// !!!!! Important note: The size_t parameter is
// implicit. Do not write it directly into
// the function call. !!!!!
void* operator new(size_t size);
void* operator new(size_t size, void* ptr);
void* operator new(size_t size, int flag);
};
/////////////////////////////////////////////////////////////////
void* X::operator new(size_t size)
{
void* ptr;
cout << "Standard class new called.\r\n";
ptr = (void*) ::new unsigned char[size];
return ptr;
}
/////////////////////////////////////////////////////////////////
void* X::operator new(size_t size, void* ptr)
{
size = size;
cout << "Placement class new called.\r\n";
return ptr;
}
/////////////////////////////////////////////////////////////////
void* X::operator new(size_t size, int flag)
{
void* ptr;
cout << "Overloaded class new called. ";
cout << "Flag was " << flag << ".\r\n";
ptr = (void*) ::new unsigned char[size];
return ptr;
}
/////////////////////////////////////////////////////////////////
void X::operator delete( void* ptr)
{
cout << "Class delete called.\r\n";
free(ptr);
}
/////////////////////////////////////////////////////////////////
int main()
{
X* objl = new X;
// Remember the size_t parameter is implicit
// The standard class new is called
// void* X::operator new(size_t size)
delete objl;
X* obj2;
void* buf = (void*) ::new unsigned char[sizeof(X)];
obj2 = new(buf) X;
// Remember the size_t parameter is implicit
// The placement class new called
// void* X::operator new(size_t size, void* ptr)
free(buf);
X* obj3 = new(64) X;
// Remember the size_t parameter is implicit
// The overloaded class new called
// void* X::operator new(size_t size, int flag)
delete obj3;
}
// ~~~~~~~ Code snippet end ~~~~~~~
Thanks,
Nimmi