In the code snippet, I am able to access the private member variable outside the class scope. Though this should never be done, why is it allowed in this case? Is it a bad practice to receive a returned private variable by reference ?
#include <iostream>
#include <cstdlib>
class foo
{
int x;
public:
foo(int a):x(a){}
int methodOne() { return x; }
int& methodTwo() { return x; }
};
int main()
{
foo obj(10);
int& x = obj.methodTwo();
x = 20; // With this statement, modifying the state of obj::x
std::cout << obj.methodOne();
getchar();
return 0;
}
And regarding this method, what does the return type convey ? And also when should I have return type of this kind ?
int& methodTwo() { return x; }
PS: I am sorry if the subject line is vague. Can someone change it to the content relevant here. Thanks.
private
does not mean "this memory may only be modified by member functions" -- it means "direct attempts to access this variable will result in a compile error". When you expose a reference to the object, you have effectively exposed the object.
Is it a bad practice to receive a returned private variable by reference ?
No, it depends on what you want. Things like std::vector<t>::operator[]
would be quite difficult to implement if they couldn't return a non-const
reference :) If you want to return a reference and don't want clients to be able to modify it, simply make it a const
reference.
Returning private members as reference is perfectly valid and the programmer who writes a class is responsible to carefully choose if this should be allowed. This link gives an example when this can be done.
This code:
int& methodTwo() { return x; }
Means that the function returns a reference to an integer. Just like when passing a value by reference to a function, if the return value of methodTwo
gets changed, so does the value that methodTwo
returned. In this case, class field x
.
In the code you have written, this means that you are letting the private variable x
escape its scope (a class field) and be passed around in the outside world. This certainly is a bad practice (because x
can be changed in ways that may break class foo
, but it is certainly allowable.
Remember public/private/protected are compile-time only. Once your application gets compiled, private fields sit next to public fields and there is no protection against modification. The same is true for managed languages like C# and Java.
You should generally avoid returning references because it makes it crazy-hard to understand when constructors/destructors get called. However, returning a reference can be faster. If your method returned a struct type that was HUGE, returning a const reference to that same struct type should only take four-to-eight-bytes (a pointer to that object). However, there are better ways to optimize for this sort of thing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With