We can all agree on public variables being bad for encapsulation and all that. However, I noticed a lot of code that does this type of stuff:
class foo {
pri
This construction may be used for debugging purposes.
If you have a public variable, you can't monitor its usage easily. Converting it to a pair of private variable and method-returning reference will allow you to put a breakpoint and/or log the calls.
However, separate getter and setter would serve the same purpose even better, so this is just an advantage over plain public variables.
I wrote this once. I planned later to go back and replace the field getter with something that returned a stack object to something that could be cast to the original type and assigned to by the original type. This allowed me to go back later and intercept all assignments to put validations in.
Kinda overpowered techinque. None of the other coders on the project could understand it at all. The whole stack got ripped out.
I would strongly discouraged returning a non-const reference to a private variable. Not because it breaks encapsulation, but because it is unnecessary: Why not make the variable public in the first place?
Breaking encapsulation is bad, yes, but that does not mean that every variable should be private. Some variables are meant to be read and modified from the user, so it would make sense to make them public. For example, take std::pair, it has 2 public member variables, first and second. That's not bad practice.
The only time it doesn't make sense is when the variable is not supposed to be written to. That would be bad, as it would actually break encapsulation and make the whole program hard to debug.
There's a recurring mantra, that getter/setter functions should be used to encapsulate your data. Hence many (unexperienced or coffee-overloaded) programmers get the idea they should use something like:
int& integer() { return integer_; }
but that isn't much different from simply writing:
class foo {
public: // <<<
int integer_;
string someString_;
// ...
};
Well, it adds a function call, but you cannot control what the client does with the reference.
If you really want to provide a getter function write:
const int& integer() const { return integer_; }
A corresponding setter function looks like:
void integer(const int& value) {
integer_ = value;
}
I have to partially disagree both with @πάνταῥεῖ and @Rakete1111 's answers, considering how a class's definition is something that may evolve over time.
While it's true that, often, these getter methods are written by someone who's just heard the "no exposing members" mantra, they can also have legitimate uses:
vector<bool> works; when you call its operator[] you don't get a boolean&, you get some kind of proxy which, when assigned or assigned-to, does the appropriate bit extraction or setting.To sum up: The "dummy" non-const-reference getter can be a stub for other, meaningful, code.
That being said, it is often a good idea to just make the getter return a const reference or a value. Or just exposing the field in those cases where it's appropriate (and there are some of those too).