Actually I find myself never requiring to make my operators friends. Usually they can do whatever they need to do through the public interface.
Case in point... such an operator probably should be written like this:
1 2 3 4
|
inline MyMatrixType operator * (double a,const MyMatrixType& b)
{
return b*a;
}
|
No friendship necessary. Calling the other * operator means no duplicate code.
Although where friendship is extremely useful is where you have tight-knit classes. It's not always wise to have one class to encompass everything, but you don't want to have to expose a lot of your internals to the public interface, either. friendship is the necessary middleground between two poor extremes.
I have a good example of this in something I did recently, but I'm running out of time, so I'll try and edit this post to include it when I get home.
EDIT:
So in a recent project of mine (for a game), I have two classes:
- Map (which represents the game map, where walls are, etc)
- MotionRect (which represents an object moving through the map. Something that needs to hit walls, etc)
The zinger is, I want to have some coarse exclusion when I do collision detection. So instead of checking every wall every time, I can take the MotionRect's position and use it to only check nearby walls.
Without friendship, the only way I could make this work would be to publicly expose either MotionRect's or Map's internals. Basically I'd have two options to choose from:
- MotionRect would need to see all of the walls in Map so it could pick out nearby walls. This blows a giant hole in Map's encapsulation. (bad option)
or
- Map would need to be aware of MotionRect and its members and do all the collision checking internally. This destroys MotionRect's encapsulation and forces MotionRect to be a dependency of Map... when Map really should not know anything about MotionRect (even worse option)
Fortunately, with friendship I can easily create a Map::Block class that acts as a "subsection" of the map. It alone can be exposed to Map's internals, preserving Map's encapsulation, while still serving as a separate entity.