Changing variables through return value?

Just confirming that my thought process on this is correct.

Below is a wiki sample code from : http://www.cplusplus.com/doc/tutorial/templates/

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  // overloading members on constness
#include <iostream>
using namespace std;

class MyClass {
    int x;
  public:
    MyClass(int val) : x(val) {}
    const int& get() const {return x;}
    int& get() {return x;}
};

int main() {
  MyClass foo (10);
  const MyClass bar (20);
  foo.get() = 15;         // ok: get() returns int&
// bar.get() = 25;        // not valid: get() returns const int&
  cout << foo.get() << '\n';
  cout << bar.get() << '\n';

  return 0;
}
modifying private members of a class through return value
... and it would be considered bad class design.

See here for a related discussion: http://stackoverflow.com/questions/27209848/changing-a-members-variable-value-inside-another-classes-function
would be considered bad class design.

Not necessarily.

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.
Last edited on
To *this, yes, but to a private data member as the quoted section was about?
> 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
closed account (48T7M4Gy)
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.
To *this, yes, but to a private data member as the quoted section was about?
It's indirect, but *this is an interface to std::ostream's private members!

It doesn't necessarily allow unrestricted modifications directly to all its' private members, but that's a good thing. See @JLBorges' post above.
Last edited on
It's indirect, but *this is an interface to std::ostream's private members!
1
2
std::ostream foo;
std::ostream & bar = foo;

You do claim that bar is more of an interface to foo than foo itself?
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 [&] (int const 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.
Last edited on
Topic archived. No new replies allowed.