Inheritance is for 2 sorts of a "is a" relationship.
The first is when you are specialising or generalising.
As in:
A Bond is an Instrument, and a European is an option
But an option on an equity is not an equity.
So an equity object might be a member of an option class, but not a base.
Then there is the other way up.
A probability is a real, but only a subset of them.
A bond default has a probability, but is not a kind of probability.
There is also "implemented in terms of". This might best be thought of as a wrapper class.
If you are using someone else's libary, you may well have horrible data structures that you want to isolate from the rest of your code.
An example might be a class which has an old-style C array as a member with no array bound checking. You could derive from it and add bound checking without breaking much code.
Friends often come up in operator overloading where to make the functions members can get painful.
Also again they are useful in interfacing.
Many libraries require that you give them a function for the library to call when it has some data to give you, or some event has occurred. This is common in data feeds for instance.
The functions to start threads require that you give them a function to "call" to start the thread in.
These types function must have exactly the types of parameters that they require, esle they crash horribly.
However member functions get passed a this pointer, even though it does not appear in the parameter list. That means 4 (or 8) bytes are put on the stack, meaning that member functions cannot be used for this. So if you want them to work closely with a class, then a friend is the way forward.
It is also useful occasionally when you have to do dark magic in getting Excel talking to C++ in unusual ways.