Actually, implementing The Big Three/Five again and again also indicates a flawed design. These methods are only needed for low-level classes that deal with custom ownership or resource semantics. If you end up providing them in every C++ class, you haven't understood the concept.
To elaborate a bit, C++ uses value semantics by default: you can copy and assign values, pass them to functions and return them from functions. Objects behave like values, whether they're class instances or integers. Now, whenever you deviate from that, you should have a reason to do so. A class is copyable/movable by default if all its members can be copied/moved one by one, and usually, this is enough.
Then there are cases where you don't want copy/move semantics of values. For example, your class might:
- have a resource owned only by one instance
- have a resource owned and shared by multiple instances
- store a pointer to a stateful base class which requires a deep copy
- store a pointer to an interface on which a function is invoked
- be registered at another class, and a pointer to itself needs to be rebound
You can now either rewrite The Big Five and increase your LOC and maintenance effort, or you can use smarter classes to take care of your copy/move semantics:
- std::unique_ptr for single ownership
- std::shared_ptr for shared ownership
- aurora::CopiedPtr for deep polymorphic copies
- std::function for functionals
- your custom observer-like class that automates such dependency rebindings
In many cases, rethinking the design and using low-level building blocks for abstraction in high-level classes helps avoid re-writing The Big Five. Whenever that's possible, do it. The Big Five are a pain to write and maintain, there's no clean way around code duplication, and it's incredibly easy to introduce bugs whenever the object state changes.
There are still cases where this is simply not possible by nature. For example when you're implementing a low-level building block itself. Or when member-wise copy/move doesn't give you the control you need for rollback semantics in exception safety scenarios.