3

I know about the rule of five which states that if you implement a destructor, you should most likely also implement a copy constructor, copy assignment operator, a move constructor and a move assignment operator.

However if I implement a move operator, do I absolutely have to implement a copy counterpart, or is it just best practice?

  • 1
    If you don't need it you can mark a copy constructor `= delete`, but never leave it default in the condition when the rule of five applied. – 273K Jul 12 '21 at 20:37
  • It is just best practice. There are valid use cases for objects that are movable and not copyable. But the reason that practice exists is because there are a lot of confusing rules around which constructors/operators the compiler will give you by default when you explicitly override a subset. It's much more maintainable to list out your desired behavior explicitly with `= default` and `= delete`. – 0x5453 Jul 12 '21 at 20:37
  • Does this answer your question? [Rule-of-Three becomes Rule-of-Five with C++11?](https://stackoverflow.com/questions/4782757/rule-of-three-becomes-rule-of-five-with-c11) – prehistoricpenguin Jul 13 '21 at 03:20

1 Answers1

7

The "Rule of Zero" may be applicable to your situation. Why are you providing a move constructor or move assignment operator in the first place? Is it because your class represents unique ownership of some resource? If so, it may be better to encapsulate ownership of that resource in a unique_ptr member or something similar. Then, you don't need to write the move constructor and move assignment operator anymore. The compiler will generate them automatically, which will move the unique_ptr member and thus transfer ownership. The compiler will also ensure that the class is not copyable.

OK, but let's say that for some reason the Rule of Zero is not appropriate to your class. What will happen if you declare only a move constructor? Then, the compiler will implicitly disable copying for your class, which will mean that objects of your class type can only be initialized from rvalues of the same type, and not from lvalues. The Rule of Five tells you that it is better to be explicit about this situation instead of leaving it to the reader to guess what the compiler is doing. So, it is best practice (but not required) to define the copy constructor as = delete;.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • Thank you. It is not something that is applicable in my real life code, but a question that was asked in prior exams and I was totally confused as how to reason my answer. Now I have a better understanding of it. – Christian Kammerer Jul 12 '21 at 20:45
  • Good to see this in exams. Too many courses seem to leave this vital concept out completely. – user4581301 Jul 12 '21 at 21:28