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()
count--;

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);
}
else
: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).