Regarding
“I know I shouldn't call non-private setters directly to avoid problems if the setter gets overwritten in a derived class.”
This is largely not a problem. Even with virtual setters, the definitions used when constructing a class A
are the ones for dynamic type A
. C++ is safe that way, as opposed to Java and C# (where you risk that a virtual call ends up in derived class code before the base class invariant has been established, and bang).
Regarding best practice, it is to be critical of setters and getters. They do have a purpose in a language with introspection, where e.g. "designer" tools can use them, but not so much in C++. So, best practice is to always ask, do I really need them, can I design some other way (e.g. move
instead of setxy
(which may not sound very different, but consider a call from a constructor – move
doesn't make so much sense during construction)).