When should you use friend classes?
friend
usually accounts for where you would normally use one single class, but you have to use more because they have different life-times or instance counts, for example. friend
ship is not transferred or inherited or transitive.
Get/Set is quite terrible, although better than it could be. friend
allows you to limit the damage to just one class. Usually you will make an intermediary class which is friended.
class MyHandleIntermediary;
class MyHandle {
friend class MyHandleIntermediary;
private:
HANDLE GetHandle() const;
};
class MyWidget;
class MyHandleIntermediary {
friend class MyWidget;
static HANDLE GetHandle(const MyWidget& ref) {
return ref.GetHandle();
}
};
class MyWidget {
// Can only access GetHandle() and public
};
This allows you to change the accessibility of friendship on a per-member level and ensures that the extra accessibility is documented in a single place.
Do Inherited Classes have the same friends as there base classes? e.g if i declare class foo as a friend of class base, will class der (derived from base) also have foo as a friend?
The rule with friend keyword is:
Friendship attribute is not inherited.
So No friend of base class will not be friend of Derived class.
What are the special case situations when a friend class should be used?
Frankly, (IMHO) using friend classes is mostly done to achieve some things for rather ease of usage. If a software is designed taking in to consideration all the requirememtens then there would practically no need of friend classes. Important to note perfect designs hardly exist and if they do they are very difficult to acheive.
An example case which needs friend class:
Sometimes there may be a need for a tester class(which is not part of the release software) to have access to internals of classes to examine and log certain specific results/diagnostics. It makes sense to use friend class in such a scenario for ease of usage and preventing overhead of design.
I am making a winapi wrapper in which I want to make class WinHandle
a friend of class Widget
(to access some protected members). Is it recommended? Or should I just access them using the traditional Get/Set functions?
I would stick to the traditional setter/getter. I rather avoid using friend where I can get working through usual OOP construct. Perhaps, I am rather paranoid about using friend
because if my classes change/expand in future I perceive the non inheritance attribute of friend causing me problems.
EDIT:
The comments from @Martin
, and the excellent answer from @André Caron
, provide a whole new perspective about usage of friend
ship, that I had not encountered before & hence not accounted for in the answer above. I am going to leave this answer as is, because it helped me learn a new perspective & hopefully it will help learn folks with a similar outlook.
Friend is used for granting selective access, just like the protected access specifier. It's also hard to come up with proper use case where use of protected is really useful.
In general, friend classes are useful in designs where there is intentional strong coupling: you need to have a special relationship between two classes. More specifically, one class needs access to another classes's internals and you don't want to grant access to everyone by using the public access specifier.
The rule of thumb: If public is too weak and private is too strong, you need some form of selected access: either protected or friend (the package access specifier in Java serves the same kind of role).
Example design
For instance, I once wrote a simple stopwatch class where I wanted to have the native stopwatch resolution to be hidden, yet to let the user query the elapsed time with a single method and the units to be specified as some sort of variable (to be selected by user preferences, say). Rather than, have say elapsedTimeInSeconds()
, elapsedTimeInMinutes()
, etc. methods, I wanted to have something like elapsedTime(Unit::seconds)
. To achive both of these goals, I can't make the native resolution public nor private, so I came up with the following design.
Implementation overview
class StopWatch;
// Enumeration-style class. Copy constructor and assignment operator lets
// client grab copies of the prototype instances returned by static methods.
class Unit
{
friend class StopWatch;
double myFactor;
Unit ( double factor ) : myFactor(factor) {}
static const Unit native () { return Unit(1.0); }
public:
// native resolution happens to be 1 millisecond for this implementation.
static const Unit millisecond () { return native(); }
// compute everything else mostly independently of the native resolution.
static const Unit second () { return Unit(1000.0 / millisecond().myFactor); }
static const Unit minute () { return Unit(60.0 / second().myFactor); }
};
class StopWatch
{
NativeTimeType myStart;
// compute delta using `NativeNow()` and cast to
// double representing multiple of native units.
double elapsed () const;
public:
StopWatch () : myStart(NativeNow()) {}
void reset () { myStart = NativeNow(); }
double elapsed ( const Unit& unit ) const { return elapsed()*unit.myFactor; }
};
As you can see, this design achieves both goals:
- native resolution is never exposed
- desired time unit can be stored, etc.
Discussion
I really like this design because the original implementation stored the multiple of native time units and performed a division to compute the elapsed time. After someone complained the division was too slow, I changed the Unit
class to cache the dividend, making the elapsed()
method (a little) faster.
In general, you should strive for strong cohesion and weak coupling. This is why friend is so little used, it is recommended to reduce coupling between classes. However, there are situations where strong coupling gives better encapsulation. In those cases, you probably need a friend
.