views:

363

answers:

5

I'm currently getting through the http://www.cplusplus.com tutorial and I came across this section here: http://www.cplusplus.com/doc/tutorial/inheritance.html that deals with the subject of friend functions and friend classes in C++.

My question is, when When is it prudent to use friendship when creating a program?

The only clue I got was in an example inside of the article that demonstrated a friend function that 'duplicated' an object.

+5  A: 

There are some really good rules of thumb for this in Marshall Cline's C++ FAQ Lite.

The whole thing is good but see, in particular, "Do friends violate encapsulation?" for examples of the right way to use them and when it's best to split classes and declare them friends.

tgamblin
+4  A: 

Friend functions exist in order to present free functions as a contiguous part of the class interface. There are a few places where free functions are part of a class interface. Example: Suppose you have an arbitrary-precision class BigNum. Here are some obvious candidates for friend functions:

// binary operators where BigNum isn't the left-hand operand
BigNum operator+ (int, BigNum);
BigNum operator- (int, BigNum);

// stream operators
std::ostream &operator<< (std::ostream &os, const BigNum &num);
std::istream &operator>> (std::istream &is, BigNum &num);

Now, given those two examples, in many cases the binary operators don't need to be friends (e.g. I can implement int + BigNum by delegating to BigNum + int, which is a member function and thus already has full access). But it all depends on what your needs are for performance, and what you are willing to expose through the class's public member functions.

Tom
I agree about the << and >> operators. But for your other example - won't it be easier if you just define a conversion from int to BigNum?
Boyan
Yeah, in the case of BigNum, because an int is always also potentially a BigNum. In other cases, it may not make sense to construct an object out the LHS of an operator.
Tom
Automatic conversions are usually a bad idea. They can interact with type determination and function overloading in weird ways.
David Thornley
+3  A: 

One good application for friend classes is the Memento design pattern.

Nemanja Trifunovic
A: 

As friends generally violate the data-hiding mechanisms, they have to be used only when really needed. If your design relies heavily on friends, it's probably wrong in some way.

An example of when you can't do without friends is overriding the << and >> stream operators. Also, friend classes are often used in the implementation of some design patterns - "Iterator" comes to mind.

Boyan
Well, overriding the stream operators doesn't imply making them friend. If some information about an object is displayed using the << operator, we can suppose that this bit of information is public and hence that there is a getter for accessing it.
Luc Touraille
@Luc: The reason for overriding the stream operators as friends is that the stream class (ostream or istream) resides on the left side of the operator. So if you want to override the operator using a member function, it must be a member of ostream or istream. But you can't do that, so you use friend
Boyan
Friends don't violate data-hiding. Friends merely allow a class's encapsulation to include free functions, rathern than just member functions.
Tom
@Tom: By 'merely' allowing that, you have to change something outside of the class when you change the internal representation of the class. And that's a violation of data-hiding.
Boyan
@Boyan - No. A friend is a part of the class, even if it is not syntactically a member. A friend should probably be implemented in the same source file that the rest of the class in, anyhoo.
Tom
@Tom: I think we're talking of the same thing using different words. For me, something that's outside of the class shouldn't be called "a part of the class" - but probably your point of view is also valid. But I think you'll agree that, part or not part, friends shouldn't be used excessively.
Boyan
@Boyan - yes, it sounds like we're in agreement about the concepts. And yes, friends should be used only when absolutely necessary (i.e. the equivalent functionality isn't accessible of feasible through the public interface).
Tom
A: 

I only used friend methods and properties for use within the class itself for clone itself or assigning another object to itself. That was largely superseded we refactored the design to implement of the Memento Design pattern in our design.

The Memento is created by the same mechanisms used to save and load the object. i.e. the Memento creates a stream, the object writes to it, and the memento can be passed to any other object of the same class to make it an exact duplicate of the object creating the memento.

Sometimes there are cases when objects need to work really close together in which case I simplify their interaction by aggregating them behind another object. Variables that would be "friend" variables and only visible to the other objects are private to the class doing the aggregating.

RS Conley