The idea of a "smart pointer" type (not to be confused with a "fancy pointer" type, which we'll cover in Chapter 8, Allocators) is that it's a class--typically a class template--which behaves syntactically just like a pointer, but whose special member functions (construction, destruction, and copying/moving) have additional bookkeeping to ensure certain invariants. For example, we might ensure the following:
- The pointer's destructor also frees its pointee--helping to solve memory leaks
- Maybe the pointer cannot be copied--helping to solve use-after-free
- Or maybe the pointer can be copied, but it knows how many copies exist and won't free the pointee until the last pointer to it has been destroyed
- Or maybe the pointer can be copied, and you can free the pointee, but if you do, all other pointers to it magically...