For my math library I found operator overloading to be a must - surprisingly, not for readability reasons, but for consistency and the ability to actually remember how the function is named.
In the beginning I used mixed paradigm: sometimes call multiplication operator*= sometimes call it Multiply, sometimes call it MultiplyBy, sometimes MultiplyByConstant, MultiplyByVector (for different input types), etc. Similar story with the other operators.
Then I ran into two major problems. First was that when I wrote template functions, I had to use one name for the multiplication/addition/subtraction/assignment operators. But most importantly I ran into human memory issues: operator*= has unquestionable and unmistakable semantics, so it was easy to remember the function names (you can't get autocomplete for the member functions of the unknown template parameter
code::blocks fails to give correct autocomplete with templates
True, readOnlyPrice is public, but, because of its name, every sane programmer will think twice before modifying it, and if not, well, you will know who to fire first.
That's incredibly obtuse. "We don't need to use language features that enforce access restrictions, because we name our variables readOnlyXXX, and that way we can save a whole line of code!" Surely the sane programmers have already left.
Well, I was complaining from the lack of the programming feature I need: read only access public, write access private. You are telling me that I should impose restrictions on my code that do not conform to my requirements, and create extra work for me. Instead, you should tell me which language feature serves my purpose.
The notion of changing your requirements to meet the specific design decisions/imperfections/flaws of the language is a lot more obtuse than the dirtiest programming hack that serves your purpose.