Smart pointers are class templates that manage a heap object and free it automatically when they go out of scope. You get lifetime handling without ever writing delete.
unique_ptr models sole ownership. It can be moved but not copied. It is as small and fast as a raw pointer, which makes it the default choice.
shared_ptr models shared ownership through a reference count. The object dies when the last owner does. It costs an extra control block and atomic count updates, so use it only when no single object can be the owner.
weak_ptr owns nothing. It observes an object held by shared_ptr and can tell whether it is still alive. You call lock() to get a usable shared_ptr, which is empty if the object is gone.
Rewriting in plainer words…
This answer doesn't lend itself to a diagram - it reads best . No credits were charged.