In C++, copying is a very distinct operation that varies depending on the object that you deal with.
If your class does not own any resource, consists only of trivially constructable types and does not encapsulate any logic, not implementing any custom constructors or destructor is actually a good practice.
Copying becomes more complicated when your object becomes more complicated too, for instance, with classes holding pointers.
To make a deep copy of the object, you must implement your custom copy constructor where you perform additional memory allocation dedicated for the copied object.
Having std::make_shared only in a constructor allows you to control the dynamic memory allocation.
When you put a non-copyable type inside your class and you don't implement a custom copy constructor, the compiler implicitly deletes the constructor of your class as well.
Whenever you add a copy constructor to your class, you must add a default constructor as well.
Another example is classes which are supposed to persist a cache specific for single class instance.
Adding a custom copy constructor may become a fix for the autogenerated default copy constructor resulting in unexpected output
Consider using std::weak_ptr if you need to implement a caching-like mechanism.