If I have three classes, A, B, C. A and B are friends (bidirectionally). Also, B and C are friends (bidirectionally). A has a pointer to B and B has a pointer to C. Why can't A access C's private data through the pointer?
Just to clarify: This is a pure theoretical C++ language question, not a design advice question.
Friendship in C++ is not transitive:
John is a friend of mine and he can use my wireless connection any time (I trust him).
John's friend Tim though is a waster and though John is my friend I do not include Tim as a friend, and thus I don't let him use my wireless connection.
Friendship is NOT inherited
Also John's children are a bunch of hooligans so I don't trust them either they are definitely not my friends nor are my own children who I trust as far as I could throw them.
Though our children can not directly accesses the wireless they can get access to it if they go through us. So John's children can access my wireless if they access it via John (ie they are supervised and protected by John).
Also, friendship is not symmetric.
John has a goverment job so he unfortunately is not allowed to trust anyone, especially when it comes to wireless.
You are always your own best friend.
This allows things like copy constructors where you can access the private member of another object even though there is no real accesses.
So I am also automatically friends with all my clones :-) as they are just other instances of myself.
Friendship in C++ is not transitive:
(A is friend of B) and (B is friend of C) does not mean (A is friend of C)
Also, friendship is not symmetric.
(A is friend of B) does not mean (B is friend of A)
You have to explicitly state that A is a friend of C to be able to access C's private stuff from within A. If adding a setter and getter to a class exposes information not meant to be exposed, you should consider friends if you can't find your design being faulty (using friend is valid. It's not a sign for bad design). If you can add a setter and getter without that being destructive to the interface, then you should avoid making other classes friends. Note that a nested class is always a friend of the nesting class. So a nested class can see the privates of the nesting class.
I just found this article while waiting for replies. It answers my question pretty well:
Friend scope in C++
Because in C++ friendship is not a transitive property. Actually it should be avoided whenever possible because it introduces complexity in a system.
Imagine that B is a mediator class and A and C are components that need to be managed, do you really think it makes sense that a button should need access to the implementation of a checkbox?
By the way, I don't see where the 'hierarchy' of your title is in the case you ask.
This is all well summed-up here:
What does it mean that "friendship isn't inherited, transitive, or reciprocal"?
-->
It means that classes derived from a friend class don't
automatically become friends (do you trust the kids of your friends?),
a friend of a friend doesn't automatically become a friend (do you
trust the friends of your friends?), and that a class declaring
another class as "friend" doesn't automatically become a friend of
that class (do you trust anyone who calls you a friend?).
from
http://yosefk.com/c++fqa/friend.html#fqa-14.4
Related
class Person
{
private BankAccount account;
Person(BankAccount account)
{
this.account = account;
}
public Person someMethod(Person person)
{
//Why accessing private field is possible?
BankAccount a = person.account;
}
}
Please forget about the design. I know that OOP specifies that private objects are private to the class. My question is, why was OOP designed such that private fields have class-level access and not object-level access?
I am also a bit curious with the answer.
The most satisfying answer that I find is from Artemix in another post here (I'm renaming the AClass with Person class):
Why have class-level access modifiers instead of object-level?
The private modifier enforces Encapsulation principle.
The idea is that 'outer world' should not make changes to Person internal processes because Person implementation may change over time (and you would have to change the whole outer world to fix the differences in implementation - which is nearly to impossible).
When instance of Person accesses internals of other Person instance - you can be sure that both instances always know the details of implementation of Person. If the logic of internal to Person processes is changed - all you have to do is change the code of Person.
EDIT:
Please vote Artemix' answer. I'm just copy-pasting it.
Good question. It seems that object level access modifier would enforce the Encapsulation principle even further.
But actually it's the other way around. Let's take an example. Suppose you want to deep copy an object in a constructor, if you cannot access the private members of that object. Then the only possible way is to add some public accessors to all of the private members. This will make your objects naked to all other parts of the system.
So encapsulation doesn't mean being closed to all of the rest of the world. It means being selective about whom you want to be open to.
See the Java Language Specification, Section 6.6.1. Determining Accessibility
It states
Otherwise, if the member or constructor is declared private, then
access is permitted if and only if it occurs within the body of the
top level class (ยง7.6) that encloses the declaration of the member or
constructor.
Click the link above for more details. So the answer is: Because James Gosling and the other authors of Java decided it to be that way.
This works because you are in the class Person - a class is allowed to poke inside it's own type of class. This really helps when you want to write a copy constructor, for example:
class A
{
private:
int x;
int y;
public:
A(int a, int b) x(a), y(b) {}
A(A a) { x = a.x; y = y.x; }
};
Or if we want to write operator+ and operator- for our big number class.
Just my 2 cents on the question of why the semantics of the private visibility in Java is class level rather than object level.
I would say that convenience seems to be the key here. In fact, a private visibility at object level would have forced to expose methods to other classes (e.g. in the same package) in the scenario illustrated by the OP.
In truth I was not able neither to concoct nor to find an example showing that the visibility at class-private level (like offered by Java) creates any issues if compared to visibility at object-private level.
That said, programming languages with a more fine-grained system of visibility policies can afford both object visibility at object level and class level.
For example Eiffel, offers selective export: you can export any class feature to any class of your choice, from {NONE} (object-private) to {ANY} (the equivalent of public, and also the default), to {PERSON} (class-private, see the OP's example), to specific groups of classes {PERSON, BANK}.
It's also interesting to remark that in Eiffel you don't need to make an attribute private and write a getter to prevent other classes from assigning to it. Public attributes in Eiffel are by default accessible in read-only mode, so you don't need a getter just to return their value.
Of course you still need a setter to set an attribute, but you can hide it by defining it as "assigner" for that attribute. This allows you, if you wish, to use the more convenient assignment operator instead of the setter invocation.
Because the private access modifier renders it visible only within the class. This method is still IN the class.
the private field is accessible in the class/object in which the field is declared. It is private to other classes/objects outside of the one it is located in.
First thing here we have to understand is all we have to do is must follow oops principles so encapsulation is say that wrap data within package(i.e. class) and than represent all data as Object and easy to access. so if we make field as non-private than
it's accessed indivisually. and it result into bad paratice.
With reflection concept in Java is possible modify fields and methods privates
Modificando metodos y campos privados con Refleccion en Java
I am looking at other's code and find one part I can't understand.
class a {
public:
function xxx () {.....}
}
class b : public a {
public:
xxxx
protected:
constructor()....
friend class a ; <= here why it is needed ????
}
As I understand, since b had already inherited from a, it should be able to use the function of a directly. What's the purpose of this "friend" declaration used for?
The friend allows a to use b's methods, not the other way around, which isn't implicit.
The design looks fishy though, a base class shouldn't care about derived classes.
friend class a; grants class a the right to access non-public members of b. So in this small example, an instance of a can call b::constructor(). Without friendship, it wouldn't be possible.
As to why, there is not enough information to answer that, other than there must be a need for instances of a to call b::constructor() (assuming that to be anything other than the syntax error it currently is).
As I understand, since b had already inherited from a, it should be able to use the function of a directly.
Yes. The friend specification though allows access the other way around (instances of a will be able to access private data and functions of b).
What's the purpose of this "friend" declaration used for?
The example above doesn't suggest any. The only situation where it may make sense is with using CRTP in certain situations (i.e. a is a template of b) but even so, if you see such a requirement ("must add friend declaration in b") it is possible that the design you're looking at is flawed.
Can you post a concrete example?
Depending on your projects/requirements, your class designs change. I have no comment on your class hierarchy but true your question is all about theories of friend usage. If you don't use friend, you will not be able to call B members from A. It is there for...cross-mating :D
It almost certainly means that there is a serious design problem. One of the basic rules of thumb for inheritance is that base classes should not need any information about derived classes. Making a a friend of b makes it possible for member functions of a to get at the internals of b objects.
I haven't yet worked out a specific case. But I am about to embark on writing some code that I feel will end up needing this; and so I wanted to know if:
Two classes can friend each other; so that they can freely access the private
and protected members of the other (I believe the answer is yes, and ofcourse I
can simply try it out!). Any detailed references or other question links with answers
are also very welcome. I am aware of forward declarations and include guard compiler
pre-directives and their use. My questions are rather more related to the semantics
of the C++ language in terms of what it can offer with regard to this possibility
of mutual friendship and how to use it properly.
Is this generally recommended? Do people employ this kind of design on a regular basis?
Under what circumstances would this be a recommended design (preferably with some
examples).
You can have mutual friendship:
class A {
friend class B;
};
class B {
friend class A;
};
Whether or not this makes sense depends entirely on the problem you are trying to solve. It definitely could make sense in certain circumstances.
The only example from my current project that utilizes mutual friendship is a container implementation: the container class is a friend of its iterator class and vice versa.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When should you use 'friend' in C++?
I was brushing up on my C++ (I'm a Java developer) and I came across the friend class keyword which I had forgotten about for a while. Is this one of those features that's just part of the kitchen sink, or is there a good reason for doing this rather than just a vanilla getter? I understand the difference in that it limits who can access the data, but I can't think of a scenario when this would be necessary.
Note: I've seen a similar question, but specifically I'm asking, is this just an advanced feature that adds no real value except to confuse people looking at you're code until they realize what you're doing?
I agree with the comments that say the friend keyword can improve encapsulation if used wisely. I'd just add that the most common (legitimate!) use for friend classes may be testing. You may want a tester class to have a greater degree of access than other client classes would have. A tester class could have a good reason to look at internal details that are deliberately hidden from other classes.
In my experience, the cases when friend (or mutable, which is a little similar) to actually enhance encapsulation of data are rare compared with how often it's used to break encapsulation.
It's rarely useful to me but when I do use it it's for cases in which I've had to split a class that was formerly a single class into two separate classes that need to access some common data/functionality.
Edit to respond to Outlaw Programmer's comment: We absolutely agree on this. One other option apart from friend'ing classes after splitting them is to make public accessors, which sometimes break encapsulation! I think that some people think that friendly classes somehow breaks encapsulation because they've seen it used improperly a lot, and many people probably never see code where it's been used correctly, because it's a rare thing. I like your way of stating it though - friendliness is a good middle ground between not allowing you to split up your class and making EVERYTHING accessible to the public.
Edit to respond to David Thornley: I agree that the flexibility that C++ allows you to do things like this is a result of the design decisions that went into C++. I think that's what it makes it even more important to understand what things are generally good and bad style in flexible languages. Java's perspective is that you should never have friend classes so that these aren't provided, but as C++ programmers it's our responsibility as a community to define appropriate use of these very flexible but sometimes misused language constructs.
Edit to respond to Tom: Mutable doesn't necessarily break encapsulation, but many of the uses of the mutable keyword that I've seen in real-life situations break encapsulation, because it's much more common to see people breaking encapsulation with mutable than to actually find and understand a proper use of mutable in the first place.
When you wish that one class (Factory) be responsible for creating instances of another class (Type). You can make the constructor of the Type private and thus make sure that only the Factory can create Type objects. It is useful when you wish to delegate the checks to some other class which could serve as a validator.
Just one usage scenario.
P.S. Really missing the "friend" keyword in C#...
A concrete instance would be a class factory, where you want one class to only be created through another factory class, so you make the constructors private, and the factory class a friend of the produced class.
It's kinda' like a 2" 12-point 3/4"-drive socket - not terribly common, but when you need it, you're awfully glad you have it.
Helps with Memento design pattern
The FAQ's section about friends: here
The FQA's section about friends: here
Two different points of view about friend.
I look at the friend construct as one of those features of the language that should be used in rare occasions, but that doesn't make it useless. There are several patterns that call for making friend classes, many of them already on this site in that "Related" bar on the right. ====>
Friendship is used when you have multiple classes and/or functions that work together to provide the same abstraction or interface. The classic example is implementing some kind of numerical class, and all the non-member operator functions (*, -, +, <<, etc) are given friendship so that they can work on the private data of the numerical class.
Such use cases are somewhat rare, but they do exist, and friend is very useful.
Here is one example, of several, I'm sure, where a friend class can be legitimately used without disregarding the reasons for encapsulation.
MyClass inherits from GeneralClass. MyClass has gotten big, so you created HelperClass to encapsulate some of the function of MyClass. However, HelperClass needs access to some protected functions in GeneralClass to properly perform it's function, so you make HelperClass a friend to MyClass.
This is better than exposing the protected functions, because they don't need to be available to everybody, but it helps keep your code organized in an OOP way to keep MyClass from getting too complex. It makes sense, because although HelperClass isn't concretely related to MyClass by inheritance, it does have some sort of logical connection to it, embodied in the code, and in design, as "friend".
I always ( and only ) use friend for unit testing private methods. The only other way I can imagine to do this would be to load up the public interface with a whole lot of testing methods, which is just too messy and so I prefer to hide the test methods in a seperate test class.
Something like this:
class cMyClassTest;
class cMyClass
{
public:
.....
private:
friend cMyClassTest;
int calc(); // tricky algorithm, test carefully
};
class cMyClassTest
{
public:
int test_calc()
{
cMyClass test;
....
int result = test.calc();
if( result == 42 )
return 1;
return 0;
}
};
friend class mean we all know that is acesss the value of variable from other class so it is mainly used for use the values so we no need to return the value of other class to main function then main to needed class member function but it having the problem that is a class is friend for other class then friend class should be in below of that class
In what kind of scenarios would we declare a member function as a 'friend function' ?..What exact purpose does 'friend function' which defies one of central concept of 'Encapsulation' of OOP serve?
You would use a friend function for the same sort of reasons that you would use a friend class, but on a member function (rather than entire class) basis. Some good explanations are in this thread.
While friend functions and classes do violate encapsulation, they can be useful in some scenarios. For example, you may want to allow a test harness to access class internals to allow you to do whitebox testing. Rather than opening up the entire class to the test harness, you could open up a particular function which accesses the internals required by the test harness. While this still violates encapsulation, it's less risky than opening up the entire class.
Also see this article for some more information about friend classes and functions.
Friend functions and classes do not violate encapsulation when you are trying to build an abstraction or interface that must physically span multiple C++ classes or functions! That is why friend was invented.
Those types of cases don't come up often, but sometimes you are forced to implement an abstraction or interface with disparate classes and functions. The classic example is implementing some type of complex number class. The non-member operator functions are given friendship to the main complex number class.
I also recall doing this when programming with CORBA in C++. CORBA forced me to have separate classes to implement CORBA servants. But for a particular part of our software, I needed to marry these together as one interface. Friendship allowed these two classes to work together to provide a seamless service to one part of our software.
Having the ability to mark a particular member function on another class as a friend to your class may seem even stranger, but it is just a way of tightly controlling the friendship. Instead of allowing the entire other class "in" as your friend, you only allow one of its member functions access. Again, this isn't common, but very useful when you need it.
See C++ FAQ Lite:
Sometimes friends are syntactically better (e.g., in class Fred, friend functions allow the Fred parameter to be second, while members require it to be first). Another good use of friend functions are the binary infix arithmetic operators. E.g., aComplex + aComplex should be defined as a friend rather than a member if you want to allow aFloat + aComplex as well (member functions don't allow promotion of the left hand argument, since that would change the class of the object that is the recipient of the member function invocation).
Sometimes public/private/protected protection level is not quite enough for real world situations. So thus we give a small get-out clause that helps without having to make methods publicly accessible.
I personally use this the same way that Java uses the 'Package' protection level.
If I have a class in the same package that needs access I will consider using friend. If it is a class in another package then I will wonder why on earth is this other class needing access and look at my design.
One point that I find relevant: member classes have access to the private parts of the containing class. This may sometimes be a better alternative to "friend".
class A
{
private:
int b;
public:
class MemberNotFriend {
public:
static void test() {
A a;
a.b = 0;
}
};
};
void test()
{
A::MemberNotFriend::test();
}
Here is a simple, concrete example of how I am using a friend function:
I have a game where each sprite object stores its info like X,Y position as private members.
However, I wish to separate the game objects from the rendering: a game object does not need the exact details of how it is rendered. A game object only stores game state, and this game state may be rendered in a number of different ways.
Thus the game object class has a friend function: render(). The render() function is implemented outside the game object class, but it can access the X,Y position position membefrs as needed to render the game object.