Update smart pointer exercise.
- Demonstrate that smart pointers have clear advantages for resource management when e.g. exceptions occur.
- Refine some comments.
- Rewrite problem 4. It was almost identical to the inheritance problem. Now focus more on smart ptrs as class members and introduce weak ptr.