By stating foo.get() = 15; we are setting the return value of x to = 15
therefore setting x in the private section of the class to = 15
Correct? I did not know you could change variable values by modifying return values. Are there examples of where this is applied/useful?
I can see how it can be detrimental to not use const for getter functions. Though I cant see much benefit to modifying private members of a class through return values rather than constructors/ member functions. I have a few ideas, but they seem impracticle in application.
It allows for method chaining --- the canonical example is that of std::ostream::operator<<() (which returns a mutable reference to *this), or most examples of operator[]() you've seen.
> modifying private members of a class through return value
>> ... would be considered bad class design.
If and only if
a. the class has an invariant which restricts the values that the member can hold
and b. the interface allows unrestricted modifications to the member
Maybe part of the problem/solution is to give the 'offending' get() a better name. Maybe calling it 'setX()' would be good interface design, albeit that it can be chained and all the rest.
There's no great significance in the name as we all know, just conventional wisdom and a low key warning.
You do claim that bar is more of an interface to foo than foo itself?
No, I didn't mean to.
Both the reference and the referent are interfaces to the same object. There's not any difference between the interface provided by foo vs. bar, since they both can be used to modify the same object with the same restrictions.
In other words a reference is transparent to the interface of its' referent.
Maybe my point wasn't clear: there's nothing inherently bad about "modifying private members of a class through a return value", as long as all the invariants are satisfied.
One point is that this statement doesn't imply returning a reference. Here's a contrived example:
Invariant: x can never decrease.
1 2 3 4 5 6 7 8 9 10
class Foo {
int x = 0;
public:
auto make_increment() {
return [&] (intconst increment_by) {
return x += (increment_by > 0)? increment_by: 0;
};
}
int get_x() const { return x; }
};
Definitely Foo::make_incrementr() allows you to modify a private member of *this through its' return value, but you can't violate the class's invariant using that interface.