Up to delete b;
everything is ok. The next line (a->setRadius(4.0);
) will trigger an undefined behaviour, because you are accessing a deleted object. The problem is that 90% of the times it will work (yes, this is a problem, because the other 10% of the times it will crash and you will lose the night finding why!)
Why this? This happens because many implementations of operator new and delete don't "ask" the memory to the OS every time they are called. They ask a big block of it and then use it a little at a time. When you delete your object, the memory is only "marked" as free, and not freed. So when you access a deallocated object, you are accessing memory that (probably) is still allocated to your process, but that you shouldn't use. In the middle some other part of your program could have allocated it and modified it, or simply the delete operator could have seen that there was so much memory "marked as free" and decided to return it to the OS, triggering a SEGFAULT if you try to access it. A "debug" version of the delete could fill it with a pattern or zero it, so that if you watch it it's more evident that it's in use or free... There are many options.
A note: I have simplified the handling of memory by new and delete. "Normally" there are some more levels of indirection. But they are irrelevant to the discussion.
On some implementations of new/delete/malloc/free on debug builds the memory, instead of being zeroed, is filled with 0xcc or 0xcdcd. This is for two reasons. If I remember correctly one is that 0xcc is the Intel instruction for the INT 3 breakpoint (and 0xcdcd is a multiple or something similar). The other is that if you watch it in a debugger, the pattern is quite obvious to see, while an "all 0x00" pattern could be more difficult to distinguish.