- design lessons from the best programming language of all time that everyone loves (not really) + access modifiers as labels (`private:`, `protected:`, and `public:`) - although Java and C#'s approach to symbol privacy may be verbose, it has one great advantage: it is stateless. - the way they're implemented in C++, it's essentially a bit more parsing state you have to keep track of - and you know what other parsing state you have to keep track of in C++? - that's right, the preprocessor.\ access modifiers, like all tokens, are affected by the preprocessor, and you have to take that into account - take the following example: ```cpp class ComfyZone { std::vector _soft_beds; #if ENABLE_HUGS public: void hug(Person& person); #endif int _remaining_hugs = 10; }; ``` - although quite contrived, it illustrates the problem pretty well - (before you ask, `_remaining_hugs` needs to be always present because it has to be (de)serialized no matter if hugging functionality is compiled in. otherwise we'd get data loss.) - we intended for `_remaining_hugs` to be private, but if hugs are enabled, it becomes public. - this can be _very_ hard to spot if you have a big class with lots of declarations inside. - this can be worked around by banning access modifiers from appearing in `#ifdef`s, but you have to *realize* that this might happen - and I've seen instances of this exact thing occurring in the Unreal Engine codebase, which is *full* of long lists of declarations (made even longer by the prevalence of `UPROPERTY()`s) - even if we didn't have the preprocessor, that access modifier is state _you_ have to keep track of - I very often find myself needing to scroll upward after Ctrl-clicking on a field or function declaration, just to find out if I can use it - (thankfully IDEs are helpful here and Rider shows you a symbol's visibility in the tooltip on hover, but I don't have Rider on code reviews)