Sunday, October 21, 2007

set_new_handler in

The correct way of overriding the new operator can be something. Here i try to highlight how one can go about doing so .

typedef void (*new_handler)();


In the new header file , a typedef new handler is defined . This typedef basically refers to
the function that the new operator will call if it is not able to allocate memory properly.
Generally the new operator specification looks for the new_handler to allocate more or release
memory so that the new operator can call it properly.

new_handler set_new_handler(new_handler handler);

is a function also found in that installs the new handler . A typical implementation
of this should return the old_handler that was replaced.

The new operator throws std::bad_alloc exception when it is not able to allocate memory.

Class specific handlers can be installed for class specific new operator .
The code for managing the operator and the handler can go in one templatised base class.
Derived classes can then inherit from this class . The base class is very specialized class
as it only provides only one type of functionality.Such type of classes are called mixins.

template
class NewHandler{
public:
static new_handler set_new_handler(new_handler handler);
static void* operator new(size_t size);

private:
static new_handler currentHandler;
};

template
new_handler NewHandler::currentHandler;

template
new_handler NewHandler::set_new_handler(new_handler handler){
new_handler oldHandler = currentHandler;
currentHandler = handler;
return oldHandler;
}

template
void* NewHandler::operator new(size_t size){
new_handler globalHandler = std::set_new_handler(NewHandler::currentHandler):
void * memory;
try{
// try to allocate memory using global new operator
memory = ::operator new(size);
}catch(std::bad_alloc &){
std::set_new_handler(globalHandler);
// propogate all the exceptions
throw;
}
// reinstall the saved gloabal handler
std::set_new_handler(globalHandler);
return memory;
}

Now any class X can use NewHandler like this :

class X : public NewHandler {
};

No comments: