views:

113

answers:

4

Is the passing by reference of a private variable in a class to be directly changed outside that class acceptable practice? Or is this something that the compiler 'should' pick up and prevent?

Example:

//-------------------------------------------
class Others
{
public:
 Others() {};
 void ChangeIt(string &str) { str = "Changed by Others"; }
};

//-------------------------------------------
class Locals
{
private:
 string PrivateString;
public:
 Locals() { PrivateString = "Set by Locals"; };
 void VisitOthers() { Others o; o.ChangeIt(PrivateString); }
 const string GetString() { return PrivateString; }
};

//-------------------------------------------
int main(void)
{
 Locals lo;
 cout << lo.GetString() << "\n";
 lo.VisitOthers();
 cout << lo.GetString() << "\n";
 return 0;
}

Output:

Set by Locals
Changed by Others

I need to do something like this using other/different objects, private to the owner class, but changeable by others when needed. Last thing I want is for this kind of practice to come back & byte me in the future.

What is essentially worrying me, is that I would like to view the class/struct as basically a pointer to a buffer, and the member's address as offsets into this buffer, so that even if you pass the pointer-value of a member it would be useless without the base-pointer of the class/struct to which it belongs. This is what I instinctively feel should be the case, so that the above example should not even be possible.

+4  A: 

There is nothing to prevent, you pass your private member by reference. The function you are calling isn't accessing your private member, it is changing it's own argument (that happens to be the member of some class). The code is OK, but the important thing is that the function you called doesn't keep a reference to your private member.

Nikola Smiljanić
+2  A: 

As the designer of the class, C++ won't prevent you to hand out reference to class private members to anyone. It may however be advisable to restrict such access to only authorized entities e.g. friends, in which case access to such private members is not really a big concern as it is 'by design'.

EDIT 2:

The mutating version of operator[] for a class also typically provides an interface for the external entities to modify the private members.

Chubsdad
+1  A: 

This is not good practice. If you want other objects to modify your object, then go for

Friend classes and Friend functions

bjskishore123
I'm using pure virtual base classes, so would not know who the friends are.
slashmais
If you are using pure virtual functions, virtual base classes and multiple inheritance, Then you can go for sister class deligation.Read more athttp://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.10But in the first place, i would recommend not to change private content in other class. You can process string in Others class and return modified string to Owner, so that it will be assigned in Owner itself.
bjskishore123
In the example, Locals is just using Others to get a job done. What is wrong with that? A class should be able to manipulate its own private members any way it likes? - By the same logic, you wouldn't be able to do anything with a private string member. If you want to invoke a string method on it, you would be passing a reference to the private member as the `*this` argument for the string method!
UncleBens
@bjskishore: too large datasets to have copies passed around; @UncleBens: the worry is the access to a private member, not what is being done to it.
slashmais
@slashmais: I think, delegation design pattern would suit your requirement. Check out at http://en.wikipedia.org/wiki/Delegation_patternComplex C++ example
bjskishore123
+1  A: 

Passing private members is totally okay. You would indicate that VisitOthers() does not change your object by making it a const method. If the method was:

void VisitOthers() const {Other o; o.visit(PrivateString);}

you would get a compiler error, because you would only allowed to pass PrivateString as a const object. It is very important though that you indicate by const and your comments which methods actually change the state of your object.

Haplo
@Hapio: By making method const, Others class can't change the object. But slashmais wants to change the private part of the object in other class. He mentioned "I need to do something like this using other/different objects, private to the owner class, but changeable by others when needed."
bjskishore123
Yes, I was just saying that the compiler will issue errors if he marks a method as const. If it is not const, there is no guarantee that the state of the object does not change.
Haplo