> I started doing everything all-public ala python (struct instead of class by default) with occasionally an m_ prefix for "intended to be private", and I've never looked back.
This is the sort of accidental complexity that access specifiers eliminated, but somehow you managed to reintroduce by trying to reinvent the wheel.
The 'm_' prefix only means "private member variable, don'access it" to you and you alone, and anyone who will stumble on your code will not be aware or obligated to follow your personal style. That would not be the case.if you simply used a basic feature of C++ that's been available since the time of "C with classes".
To me, you're the epitome of the main source of C++'s problems: programmers who failed to learn the basics of a language and instead decided to develop convoluted hacks to circumvent proper use of the language because they believe their new discovery is clever although in reality they only managed to needlessly add complexity to a code base while adding brittle and bug-prone code.
What else? Do away with memory deallocation because there's nothing of the sort in Python and your C++ code is packed with segfaults?
And by the way, the pimpl pattern is used to provide libraries a stable ABI in spite of what change might be done to the implementation. It is not a fad or a clever-looking trick.
Python has a well-established convention of _underscore for intended-to-be-private members, with no enforcement, and it works fine. Just document your conventions. The horrors of some other programmer using it wrong seem overblown to me.
In my IDE in c++ I can quickly refactor m_ to non-m to make it "semantically public" without having to edit header files, change struct packing order / ABI, etc. And most of the time I don't even bother with m_. It's one less thing to think about. I honestly don't think access specifiers are worth wasting mental cpu cycles on in most projects.
Besides, in c++ people can always cast your intricately-protected object to a void pointer and start manipulating it nefarioisly anyway. Just document and communicate, and write simple straightforward code.
I used pimpl at the time for faster recompiles when changing "private" stuff. Better build tools got me around that problem personally, but I'm sure it has it's uses.
Those access modifiers are there for a reason and they work very well in not just C++ in many other object oriented languages like C# and Java. So, using Python to justify that style of coding is a far cry from anything that is reasonable. If it work for you that's fine, but I don't think it's a good idea generally.
> Python has a well-established convention of _underscore for intended-to-be-private members, with no enforcement, and it works fine.
Python does not have access modifiers. C++ does. It makes absolutely no sense to write Python code in C++ while entirely oblivious to basic, age-old C++ features just because your background lies somewhere else and you failed or refused to learn even the basics.
And you know what actually works instead of just "working fine"? Having the compiler throw an error if a careless programmer tries to access private variables.
> In my IDE in c++ I can quickly refactor m_ to non-m to make it "semantically public" without having to edit header files, change struct packing order / ABI, etc.
Don't you understand that's completely irrelevant? Just set the private member as private and it does not matter at all which naming convention you follow. Don't you understand that having to do nothing is better than expecting team members to be prescient about your convoluted and absurd naming convention used to avoid best practices?
> Besides, in c++ people can always cast your intricately-protected object to a void pointer and start manipulating it nefarioisly anyway.
Don't you understand that't entirely irrelevant? You're trying to argue that it's ok to ignore best practices such as using member access specifyers, which actually get the compiler to validate the code, if you stick with naming conventions, but arguing that it's technically possible to circumvent compiler checks under some specific circumstances is an absurd statement. Think about it: if you feel that enforcing a coding style is enough to enforce private member access then don't you agree that the same code review that is supposed to enforce your personal style can quite easily catch your hypothetical casts?
You keep accusing me of "failing to understand" or "refusing to learn" the "best practices" of using access specifiers.
I understand them well, and I've experimented with their use in my own projects, and decided they're a minor complexity I don't need to bother with. And that decision has served me well.
Dogmatic adherence to "best practices" is silly, even when people can agree on what they are. Learn them, yes, evaluate them carefully, but ultimately choose what works best for your constraints. Including what your team's conventions are.
The programmers I've seen taking most about "best practices" generally don't think very critically about their approaches and go with dogmatic answers, often tying up their codebases in ridiculous complexity. E.g. the "best practice" now to make a website is a React.js SPA, and now every site out there takes 20 seconds to load with 10 little spinner icons while all the HTTP requests go out to their microservices on docker clusters, and everything requires a hundred-library-deep build stack.
I strongly agree with your sentiment that 'best practices' act as a replacement for critical thought, and lead to messy, overcomplicated and flawed architectures. Every "best practice" would be best delivered with a criteria list of when it's actually applicable, and a shortcomings list of situations where its not.
> and now every site out there takes 20 seconds to load with 10 little spinner icons while all the HTTP requests go out to their microservices on docker clusters, and everything requires a hundred-library-deep build stack
That’s just the cost of progress. Gotta break a few eggs to make an omelet. No pain, no gain. There are always casualties in war. Get with the times, grandpa.
This is the sort of accidental complexity that access specifiers eliminated, but somehow you managed to reintroduce by trying to reinvent the wheel.
The 'm_' prefix only means "private member variable, don'access it" to you and you alone, and anyone who will stumble on your code will not be aware or obligated to follow your personal style. That would not be the case.if you simply used a basic feature of C++ that's been available since the time of "C with classes".
To me, you're the epitome of the main source of C++'s problems: programmers who failed to learn the basics of a language and instead decided to develop convoluted hacks to circumvent proper use of the language because they believe their new discovery is clever although in reality they only managed to needlessly add complexity to a code base while adding brittle and bug-prone code.
What else? Do away with memory deallocation because there's nothing of the sort in Python and your C++ code is packed with segfaults?
And by the way, the pimpl pattern is used to provide libraries a stable ABI in spite of what change might be done to the implementation. It is not a fad or a clever-looking trick.