In this chapter, we have learned a few things about smart pointers.
std::unique_ptr<T> is a vocabulary type for ownership, and for ownership transfer; prefer it over raw T*. Consider the use of observer_ptr in situations where ownership is explicitly not being transferred, or where raw T* might be ambiguous to the reader.
std::shared_ptr<T> is a good (and standard) tool for dealing with shared ownership, where many different entities are all stakeholders in the lifetime of a single controlled object. std::weak_ptr<T> is a "ticket for shared_ptr"; it provides .lock() instead of operator*. If your class needs the ability to get shared_ptr to itself, inherit from std::enable_shared_from_this<T>. Remember to inherit publicly, and generally speaking, only at the leaves of your inheritance graph. And don't overuse these features in situations...