I have been studying classes of late and came to know about friend functions which are a way to access private data members of a class.....
My question is that since friend functions access private memebers of a class outside it's body , is it not an intrusion into data hiding??????
I mean one of the most basic difference b/w structures and classes is the default access specifier- public in structures and private in classes..... So are friend functions not a breach to the concepto data hiding?????????
#include <iostream>
class a
{
private:
int variable;
public:
void change(int A)
{
variable=A;
};
int returnA()
{
return variable;
};
};
int main()
{
a obj;
// a.variable = 1; // Doed NOT work since to access you need member function
a.change(1); // works, since we call member function
std::cout << a.returnA() << std::endl;
return 0;
}
Anurag7069 - Yes, you're absolutely right. As a rule you should never, ever use friend with classes. Unless you're forced to!
Some of the code on this site uses friend to solve problems that would be better handled by an accessor.
One of the few places I would find the use of friend acceptable is for a container's iterator. As the iterator is intimately related to its container, it's ok to exploit friend to simplify the code. But that's because the iterator is not really a separate class. It's part of a "compound class".
Andy
P.S. But adding friend temporarily to classes, to help with refactoring, can be very helpful. As long as they've all gone by the end of the process.
Accessors break encapsulation. (getters and setters are evil http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html?page=1 )
Instead of exposing the member to all the world, you just expose it to the function (however you expose all the members). In that case you could consider the function as part of the interface of the class (like a method)
Once again like many of other C++ good features say operator overloading for e.g friend with classes can be "abused" by developers limited by their own imagination. Bjarne Stroustrop created a too flexible C++ language that are good but then he obviously did not forsee how developers are going to make use of them.
I believe Java creator James Gosling learn from C++ "mistakes" and aim to avoid even providing such features in it's language specification.
I think the javaworld.com page is over-stating things a bit in this case.
It is bad (and mad!) if you implement accessors for every single private data member.; as a rule you should not access data member directly, even up the class hierarchy. But when a data member represents a meaningful property of an object, it is perfectly valid to provide an accessor for it.
On the flip side, code which calls a lot of accessors to get data from the same object, and then performs calculations using it, is a very bad thing. Esp. when there are multiple levels of dereferencing. This will only occurs when the wrong class is doing the work.
I have most often seen this latter "anti-pattern" turn up in container based code, where the container is getting the data from the objects it contains and performing the calculation, rather than getting each object to do its own share of the work.
Andy
[1] I have to admit that in practice -- due to time constraints -- I am prone relax the class hierarchy constraint, using protected. But when learning C++ it's probably a good practice to stick to as it draws attention to where you're introducing coupling.
The book I'm working out of details situations where I think friend functions are justifiable. One example is the construction of a so called "safe" pointer class. This is a class that keeps track of how many pointers are pointing to a dynamically allocated object and automatically destroys that object when all the pointers are gone or directed to point elsewhere. To do this, there are actually two classes. One class is the interface class that the user can use just like the built-in pointers. The second class is a utility class that holds the actual pointer. Only the interface class uses the second class. The user wouldn't even need to know it exists. The interface class does all the appropriate manipulations to the utility class and checks its counter to see how many other interface class objects are pointing to it. If that ever drops to zero, it deletes the class object. It seems like making the interface class a friend of the utility class is fine since the interface class is shielding it from any unscrupulous things the user might try.
The other example is where you want to overload certain operators like those used with the stream library ( << and >> ). If you overload these as member functions, the operator becomes a member of the class. But it's already a member of the standard library and we want to overload it to work with the stream library, not override it. The authors state that operator overloading should be done judiciously which means operators should do things that would make sense to the user based on how those operators work with the built-in data types. To make the "<<" operator consistent with the library, it's definition must be outside the class. If it needs to output private data members of the class object, it will need to be a friend function.
If any more experienced people have some thoughts on this, I would like to hear them.