Tu hai definito l'operatore << che lavora con l'indirizzo dell'oggetto Sim
codice:
ostream& operator<<(ostream& out, const Sim& a)
{
     out << endl << "Dati della SIM: "
         << endl << "Numero:   " << a.numero
         << endl << "PIN:      " << a.pin
         << endl << "CF:       " << a.fiscale
         << endl << "Credito:  " << a.residuo
         << endl << endl;
     return out;
}
Quando però in quest'altra funzione tu chiami <<a.mittente, mittente è un puntatore, quindi non contiene un oggetto Sim, bensì l'indirizzo di memoria di un oggetto Sim, quindi lui ti stampa esattamente quello che ci trova dentro.
codice:
ostream& operator <<(ostream& out, const Sms& a)
{
     out << endl << "Dati dell'sms: "
         << endl << "Destinatario:    " << a.destinatario
         << endl << "Data:            " << a.data
         << endl << "Costo:           " << a.costo
         << endl << "Testo:           " << a.testo;
     
     cout << endl << a.mittente << endl << endl; 
     //mittente non contiene un oggetto Sim ma l'indirizzo di un oggetto Sim
     return out;
}
Ti basta fare l'overloading della funzione in modo che se gli passi un puntatore sappia cosa andare a prendere.
Quindi oltre a quella che hai già scritto scrivi anche:
codice:
ostream& operator<<(ostream& out, const Sim* a)
{
     out << endl << "Dati della SIM: "
         << endl << "Numero:   " << a->numero
         << endl << "PIN:      " << a->pin
         << endl << "CF:       " << a->fiscale
         << endl << "Credito:  " << a->residuo
         << endl << endl;
     return out;
}