The overloaded delete operator for NullObject:

void NullObject:perator delete (void* p)
if (count != 0) // count is a static int that gets ++-ed in getInstance()

if (count == 0)
:perator delete(p);

Because the program deals with most classes as Objects (ie the base-class), delete is also overloaded for Object like this:

void Object:perator delete (void* a)
Object* p = reinterpret_cast<Object*>(a);
if ((p)->isNull()) // always returns true for NullObject, typeid for other
NullObject* no = dynamic_cast<NullObject*>(p);
operator delete(no);
:perator delete (a);

Basically, it checks if the Object is a NullObject. If it is, it calls the overloaded delete. Else, it calls the global delete.

As I said before, it works when you don't just call delete, but call it as an operator. That's why I think the memory isn't deallocated. I can have multiple NullObjects, all pointing to the same instance, and when I delete one (using the long way) the others work fine.

However, when I just go
delete aNullObject;
c++ automatically calls the destructor too (I can't remember the order in which things get called). That's where it falls apart. The NullObject is no longer seen as a NullObject (isNull() returns false).