Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Global overload of new and delete ---- Borland feature only?

Reply
Thread Tools

Global overload of new and delete ---- Borland feature only?

 
 
Nimmi Srivastav
Guest
Posts: n/a
 
      01-31-2004
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. In fact there are
quite a few things that I learned that I did not know before. For
example, while I knew that the new and delete operators can be
overloaded for classes, I did not know that that the global new and
delete operators can also be overloaded. Is this is Borland C++ only
function? I am asking this question since the code snippet below is
not compiling with my non-Borland C++ compiler.

Are there any other operators that can be overloaded globally?

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) The use of operator new or operator delete in an expression causes
the corresponding function to be called. In other words, using
operator new causes the following function to be called:
operator new()

Using operator delete causes the following function to be called:
operator delete()

[Yeah yeah, this is kinda obvious, but I am stating it for
completeness]

2) Multi-dimensional arrays can be created with new, but with some
restrictions. All the indices must be specified, and all of them,
except the first one, must be constants. Thus the following is
legitimate syntax:
int i = 2;
intptr = new int[i][2][2];

3) When arrays of class objects are created with new, only the default
constructor can be used.

4) The global new operator can be overloaded as well as over-ridden.
For this you have to define a function with the following syntax:

void* operator new (/* one or two arguments*/)
{
//body ...
}

To overload, you pass two arguments to new:
size_t and void*

To over-ride, you pass only one argument to new:
size_t

5) The global delete operator can only be over-ridden. For this you
have to define a function with the following syntax:

void operator delete (/* one or two arguments*/)
{
//body ...
}

The type of the first argument is void *. The type of the second
argument, which is optional, is size_t

6) C++ recognizes the use of operator new-with-placement-syntax. This
is basically a pointer to the area (in memory) in which the entity is
to be constructed. new-with-placement-syntax creates the object at a
specific location.

7) The global new operator with placement syntax looks like this:
:: new(location pointer) type [dimension] (initializers)

The following are optional:
::
[dimension]
(initializers)

Whenever new is used with placement syntax, you are required to
overload the operator new

9) To instantiate an array of objects, you have to use
new-with-placement-syntax

10) Do not use delete to destroy a class object that has been
instantiated by new-with-placement-syntax. The correct approach is to
call the destructor explicitly and then separately release the storage
occupied by the object

// ~~~~~~~ Code snippet begin ~~~~~~~
#include <iostream.h>

//
// Overloading new operator
// (for use with new-with-placement-syntax)
void* operator new( size_t size, void *where)
{
cout << "Overloaded new operator" << endl;
size = size; // Dummy statement avoids compiler warning
return where; // Here is what we are after
}


//
// Overriding new operator ---- initializes the returned
// memory to null
//
void* operator new(size_t size)
{
cout << "Overridden new operator" << endl;
void* ptr;
ptr = malloc(size);
if(!ptr) return ptr; // Return null if failed

memset(ptr, '\0', size); // Do init for user
return ptr; // Return ptr by value
}

//
// Overriding delete operator
//
void operator delete( void *obj, size_t size)
{
cout << "Overridden delete operator" << endl;

// The size parameter is useless here
free(obj);
}



//
// Declare a simple class (simple_1)
//
class simple_1
{
int stuff;
public:
simple_1(int arg = 16) { stuff = arg; }
~simple_1() {}
void showit() { cout << stuff << "\r\n"; }
};


//
// Declare another simple class (simple_2)
//
class simple_2
{
int a, b, c, d, e;

public:
simple_2(): a(37), b(37), c(37), d(37), e(37)
{
cout << "HeLLo!\r\n";
}

~simple_2() { cout << "Goodbye!\r\n"; }
};


//////////////////////////////////////////////////////////////////////
int main()
{

/********** 1 **********/
// Using the overloaded new operator

// Declare a void pointer that will be used to locate
// the class object
void *fetch;


// Acquire the memory necessary to bold the object
// using original global new
fetch = (void *) (::new unsigned char[sizeof(simple_1)]);


// Declare a pointer to a class object of the desired type
simple_1* X;


// Use the overloaded new-witb-placement-syntax operator to
// construct the class object, passing the constructor
// initiatizer value as the argument
X = new(fetch) simple_1(37);


// Use the object however you want
X->showit();


// Call the destructor function explicitly. There is no
// delete for the class object in this case. So if you
// don't call the destructor explicitly, it is not called
// at all
X->~simple_1();


// Release the memory used to bold the object.
//delete fetch;
free (fetch);

/********** 2 **********/
// Over-ridden new and delete operators work well with
// basic types
char* str;

str = new char[41];
delete str;

/********** 3 **********/
// Here we will use the over-ridden new and delete operators
// with classes. These work well as long as we don't use any
// arrays of class objects

simple_2* oneobj = new simple_2;
delete oneobj; // All stiLL OK for ONE class object


/********** 3 **********/
// Here we will attempt to instantiate arrays of class objects.
// We will have to use the new-with-placement-syntax
// (overloaded new operator)


// Set up the void* pointer that will locate the array
void* oarray;


// Acquire the memory for the whole array (using the sizeof
// operator). You can use standard C library routines or
// :: new for this purpose
oarray = ::new unsigned char[10*sizeof(simple_2)];


// Declare a pointer to the class object, and initialize it witb
// new-with-placement-syntax. Use the array size declarator
// The constructors for each class object is properly called.
simple_2* bunch = new(oarray) simple_2[10];
// Be careful here, using pointer-subscript
// equivalence

// After using the array of class objects, wrte a loop in
// whicb you directly call the destructor functionfor every
// class object in the array.
for (int i=0; i < 10; ++i) bunch[i].~simple_2();

// Release the block of memory holding the
// array.
//delete oarray;
free(oarray);

}

// ~~~~~~~ Code snippet end ~~~~~~~

Thanks,
Nimmi
 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      02-01-2004

"Nimmi Srivastav" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) m...
> 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. In fact there are
> quite a few things that I learned that I did not know before. For
> example, while I knew that the new and delete operators can be
> overloaded for classes, I did not know that that the global new and
> delete operators can also be overloaded. Is this is Borland C++ only
> function? I am asking this question since the code snippet below is
> not compiling with my non-Borland C++ compiler.


See below.

>
> Are there any other operators that can be overloaded globally?
>
> 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) The use of operator new or operator delete in an expression causes
> the corresponding function to be called. In other words, using
> operator new causes the following function to be called:
> operator new()
>
> Using operator delete causes the following function to be called:
> operator delete()
>
> [Yeah yeah, this is kinda obvious, but I am stating it for
> completeness]


Correct.

>
> 2) Multi-dimensional arrays can be created with new, but with some
> restrictions. All the indices must be specified, and all of them,
> except the first one, must be constants. Thus the following is
> legitimate syntax:
> int i = 2;
> intptr = new int[i][2][2];


Specifically compile time constants. The following is not OK

const int x = something(); // a constant, but not a compile time constant
int* p = new int[x];

>
> 3) When arrays of class objects are created with new, only the default
> constructor can be used.


Correct.

>
> 4) The global new operator can be overloaded as well as over-ridden.
> For this you have to define a function with the following syntax:
>
> void* operator new (/* one or two arguments*/)
> {
> //body ...
> }
>
> To overload, you pass two arguments to new:
> size_t and void*
>
> To over-ride, you pass only one argument to new:
> size_t


The two argument one is a placement new, and is already defined.

You aren't restricted to just this, any number of arguments and types are
allowed, as long as the first is size_t.

>
> 5) The global delete operator can only be over-ridden. For this you
> have to define a function with the following syntax:
>
> void operator delete (/* one or two arguments*/)
> {
> //body ...
> }
>
> The type of the first argument is void *. The type of the second
> argument, which is optional, is size_t


Global placement deletes are allowed. Again any number any typ of arguments
are OK, as long as first is void*.

>
> 6) C++ recognizes the use of operator new-with-placement-syntax. This
> is basically a pointer to the area (in memory) in which the entity is
> to be constructed. new-with-placement-syntax creates the object at a
> specific location.


That is the most common use of placement new. But really placement new is
just a way of providing extra arguments to operator new which can be used
for any purpose.

>
> 7) The global new operator with placement syntax looks like this:
> :: new(location pointer) type [dimension] (initializers)


Again, any arguments are possible, e.g.

void* operator new(size_t bytes, X* px, Y* py, Z* pz);

X x;
Y y;
Z z;
new (&x, &y, &z) int;

>
> The following are optional:
> ::
> [dimension]
> (initializers)
>
> Whenever new is used with placement syntax, you are required to
> overload the operator new


The commonest placement new (the one with one extra void* argument) is
already provided in header file <new>

>
> 9) To instantiate an array of objects, you have to use
> new-with-placement-syntax


I guess you mean instantiate an array of objects with non default ctor.

>
> 10) Do not use delete to destroy a class object that has been
> instantiated by new-with-placement-syntax. The correct approach is to
> call the destructor explicitly and then separately release the storage
> occupied by the object


Correct.

>
> // ~~~~~~~ Code snippet begin ~~~~~~~
> #include <iostream.h>


Non-standard header (this is true, despite whatever books you might have
read). Replace it with

#include <iostream> // note no .h
using namespace std;

and you are standard compliant.

>
> //
> // Overloading new operator
> // (for use with new-with-placement-syntax)
> void* operator new( size_t size, void *where)
> {
> cout << "Overloaded new operator" << endl;
> size = size; // Dummy statement avoids compiler warning
> return where; // Here is what we are after
> }


Above function is already defined in header <new> (again no .h). You
shouldn't define it again.

Rest of code compiles OK for me.

John


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Overloaded global delete is used instead of orignal global delete[] Alex Vinokur C++ 3 06-15-2012 05:12 PM
QUERY: Borland C++ 4.5 vs Borland Turbo C++ 1.01 dhruba.bandopadhyay@hotmail.com C++ 1 10-02-2006 10:57 AM
function overload (not operator overload) Ying-Chieh Liao Perl Misc 3 10-11-2004 11:24 AM
How use the overload of>> (or<<) of a class in the overload of << and >> of another class? Piotre Ugrumov C++ 3 01-25-2004 08:08 PM
overload new and delete for performance? (design) Chris E. Yoon C++ 2 07-23-2003 09:36 AM



Advertisments