Jump to content
  • Advertisement
Sign in to follow this  
bradbobak

overloading operator new

This topic is 4554 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys.. I'm making a simple library for my use and I would like all my new's to throw the exception 'sml_exc(SML_EXC_MEM)' on fail.. I know I can overload new globally (and this is what I do now), but I'm thinking of the future where I might be using my library and another library may expect new to throw 'something_else'.. Maybe I can overload new for each class.. something like:
class a
{
  public:
    a() { };

  operator new  // stuck here
};
Can someone post maybe a snippet showing me how to cause 'new a' to throw 'my_exc' on fail?? Thanks, Bradd

Share this post


Link to post
Share on other sites
Advertisement
I dont know much about exceptions or exception handling, but try putting the exception declaration and all classes that use it in a namespace.

Share this post


Link to post
Share on other sites

void * operator new(size_t size) throw (sml_exc) {
try {
A* a = ::new A();
}
catch(std::bad_alloc& ex) {
throw sml_exc(SML_EXC_MEM);
}
return a;
}


or


void * operator new(size_t size) throw (sml_exc) {
A * a = malloc(size);
if(a == NULL)
throw sml_exc(SML_EXC_MEM);
*a = A();
return a;
}


Should work...

[Edited by - visage on December 30, 2005 9:58:52 AM]

Share this post


Link to post
Share on other sites
I guess this is the same idea so I'll post this as a reply to my original question..

lets say I have this:


class foo
{
public:
foo() { }

void *
operator new(size_t size)
{
void *res = (void *)malloc(size);
if (!res)
throw (my_exc);
return (res);
}
};

class bar : public class foo
{
public:
bar() { }
};

int func()
{
bar *b = new bar();
// will the above call foo's new??
}



EDIT: Basically I just want to be able to derive a class from a base 'memory_alloc'
class to avoid making the 'operator new...' stuff in every class..


Thanks again -- Bradd

Share this post


Link to post
Share on other sites
Quote:
Original post by bradbobak
// will the above call foo's new??


Yes. Operators new and delete are inherited.

Also, just to be complete, consistent, and safe, you should overload operator delete if you overload operator new.

Share this post


Link to post
Share on other sites
Quote:
Original post by visage

void * operator new(size_t size) throw (sml_exc) {
try {
A* a = ::new A();
}
catch(std::bad_alloc& ex) {
throw sml_exc(SML_EXC_MEM);
}
}



That code is asking for trouble, invoking operator new implicitly invokes the constructor there shouldn't be any constructors be invoked inside of an overload of new since when the overloaded version is invoked implicitly the compiler automatically invokes the constructor.

That means you will at most invoke a constructor twice and at least once when it shouldn't at all (for explicit invocation). If you want to reuse an existing overload of operator new inside another overload then explicitly invoke it i.e.


#include <cstddef>
#include <new>

struct foo {

void* operator new(std::size_t size) throw() {
// explicit invocation, only allocation no constructor is invoked.
return ::operator new(size, std::nothrow);
}
// .....
};


The same holds for operator delete too.

Also the default, global operator new only throws std::bad_alloc when you include header new, it returns zero by default to indicate allocation failure. When you do include header new and you when you only want to use the no-throwing version then you have to use the overload which takes a constant reference to std::nothrow_t.

Share this post


Link to post
Share on other sites
Quote:
Original post by snk_kid
Also the default, global operator new only throws std::bad_alloc when you include header new, it returns zero by default to indicate allocation failure. When you do include header new and you when you only want to use the no-throwing version then you have to use the overload which takes a constant reference to std::nothrow_t.

Is this a change from the final draft standard? The final draft states:
Quote:
C++ Final Draft Standard, Section 3.7.3.1, Paragraph 3
An allocation function that fails to allocate storage can invoke the currently installed new_handler (18.4.2.2). [Note: A program supplied allocation function can obtain the address of the currently installed new_handler using the set_new_handler function (18.4.2.3). ] If a nothrow allocation function (18.4) fails to allocate storage, it shall return a null pointer. Any other allocation function that fails to allocate storage shall only indicate failure by throwing an exception of class std::bad_alloc (18.4.2.1) or a class derived from std::bad_alloc.

From my tests GCC, Borland and Visual C++ 8.0 all have new always throw, regardless of headers included (including with no headers included) whereas Visual C++ 7.1 follows the behaviour you describe.

Enigma

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!