edit: Reading the faq a bit longer I like the idea of the << >> operator overloading and adding as a friend of those classes, however I am not sure how this doesn't break encapsulation
How would it break encapsulation?
You break encapsulation when you allow unrestricted access to a data member. Consider the following classes:
class c1 {
public:
int x;
};
class c2 {
public:
int foo();
private:
int x;
};
class c3 {
friend int foo();
private:
int x;
};
c1
is obviously not encapsulated. Anyone can read and modify x
in it. We have no way to enforce any kind of access control.
c2
is obviously encapsulated. There is no public access to x
. All you can do is call the foo
function, which performs some meaningful operation on the class.
c3
? Is that less encapsulated? Does it allow unrestricted access to x
? Does it allow unknown functions access?
No. It allows precisely one function to access the private members of the class. Just like c2
did. And just like c2
, the one function which has access is not "some random, unknown function", but "the function listed in the class definition". Just like c2
, we can see, just by looking at the class definitions, a complete list of who has access.
So how exactly is this less encapsulated? The same amount of code has access to the private members of the class. And everyone who has access is listed in the class definition.
friend
does not break encapsulation. It makes some Java people programmers feel uncomfortable, because when they say "OOP", they actually mean "Java". When they say "Encapsulation", they don't mean "private members must be protected from arbitrary accesses", but "a Java class where the only functions able to access private members, are class members", even though this is complete nonsense for several reasons.
First, as already shown, it is too restricting. There's no reason why friend methods shouldn't be allowed to do the same.
Second, it is not restrictive enough. Consider a fourth class:
class c4 {
public:
int getx();
void setx(int x);
private:
int x;
};
This, according to aforesaid Java mentality, is perfectly encapsulated.
And yet, it allows absolutely anyone to read and modify x. How does that even make sense? (hint: It doesn't)
Bottom line:
Encapsulation is about being able to control which functions can access private members. It is not about precisely where the definitions of these functions are located.