More properly: "Time to stop defaulting to using C-style pointers to manually manage memory".
OK, time to stop using C-style pointers...
You can still use C-style pointers for non-memory management...
But you shouldn't manually manage memory yourself...
...unless you actually need to for performance reasons (which it sometimes is, even on normal projects).
That's from someone trying to manually manage memory, and instead of fixing the problem (problem: delete gets called twice), pretends the problem doesn't exist by hiding it (delete won't delete a null pointer).
It comes from a book, "Teach yourself C++ in 24 hours." I don't remember the exact reason and no longer have the book, but something about calling delete on a NULL pointer is safe, but calling it on an uninitialized pointer can lead to problems. The book mentioned setting the pointer to NULL after delete in the event that delete is called twice (why this would happen, I do not know...). I have always done this.
The most direct solution is: don't call delete twice on the same pointer.
A even better solution is: don't call delete (or new) at all*, let smart pointers do it for you.
*See previous comment of, 'except when you actually need to'
[edit:] That's not entirely to say setting an invalid pointer to null is bad. Dereferencing a null pointer crashes your program, which is good! So if there is an opportunity to use a pointer after it's been deleted, set it to null... but you shouldn't actually be calling new or delete to manage memory. If I have a raw pointer (that isn't managing memory) that's pointing at something, null is the ideal value to assign to it when it's not valid, because dereferencing null guarantees to crash, while dereferencing random memory maybe might crash, and maybe might do something incredibly weird that won't show up for several weeks or months.
In some cases it actually even makes sense (usually to avoid unnecessary checks for cleaner code) to delete twice since it has no effect - but it's important to A) know the reason why you raw pointers are set to NULL, and B) not use it to "solve" a program crashing, but actually find out why the program is crashing.
- Prefer memory on the stack over dynamic memory.
- Prefer smart pointers over raw pointers when you actually need dynamic memory.
- Use raw pointers when you actually need performance in that one area.
Note: 'by default' does not mean 'always'. And in the same way, "prefer smart pointers" does not mean "never use raw pointers".