The main reason is usually doing things like having "new" in the constructor and "delete" in the destructor. Any accidental temporary copy would typically cause a double delete eventually (or worse, leave your original with an invalid pointer for a long time, only crashing much later and being a real pain to debug).
One solution is explicitly deleting all problem operations (assignment, copy construction, etc.)
A typically better solution is to properly express your ownerships by using the correct smart pointer. In the above case, use a unique_ptr instead of a raw pointer and suddenly code that would accidentally (or intentionally) copy or assign won't compile. Problem solved without messing about with deleting default functions. If data should be shared, use a shared_ptr and data is automatically deleted at the proper point. In both cases, you don't need to worry about manually deleting anything.
Just making literally everything noncopyable for no good reason would simply look like unreflected cargo cult programming (yes, it's a thing and scarily common).