codice:
automobile& automobile::operator=(const automobile& a)
{
     modello = a.modello;  

           for(list<componente>::const_iterator it=a.componenti.begin() ; it!=a.componenti.end() ; it++)
       componenti.push_back(*it);       
return *this; // obbligatorio che sia sempre l'ultima riga.
}
Qui c'è un'imprecisione: restituisci true quando la stringa è uguale all'altra a prescindere che la lista sia uguale all'altra o no. Inoltre dai per scontato che le liste siano lunghe uguali, il che quasi mai è vero.
Corretto è:
codice:
bool automobile::operator == (const automobile& a)
{ 
     // se le due liste sono di lunghezza diversa non sono uguali.
     if (componenti.size() != a.compomenti.size()) return false;

// ok
 list<componente>::iterator it2=componenti.begin();
   for(list<componente>::const_iterator it1=a.componenti.begin() ; it1!=a.componenti.end() ; it1++)
       {
                   if(*it2 !=*it1 )
                        return false;          

                 it2++;
        }      

      // se le due stringhe non sono uguali...
      if( modello!= a.modello    )
            return false;

// se non esce prima, i due oggetti sono uguali.
return true;
}
Come mai prima hai scritto che la classe avrebbe bisogno solo dell'operatore di ug?
Cioe' quali sono i casi in cui la classe ha bisogno solo dell'operatore di uguaglianza.?
I fab four (non mi ricordo chi li abbia chiamati così) che sono:
costruttore di default, costruttore di copia, operatore di assegnamento, distruttore;
sono indispensabili quando il tipi nativi contenuti nella classe sono puntatori.
Se assegni o copi un oggetto a un altro e questo oggetto ha un puntatore, il compilatore farà una copia bit a bit dell'oggetto, quindi quando il puntatore sarà rilasciato nel distruttore, la memoria sarà liberata due volte. La prima va a buon fine, la seconda: BUM!
Tu però in questa classe usi due tipi "intelligenti" che già da soli forniscono costruttore di copia e operatore di assegnamento, quindi quando il compilatore copierà/assegnerà il tuo oggetto a un altro, automagicamente invocherà costruttore di copia/operatore di assegnamento per ognuno di questi tipi "intelligenti".
L'operatore di uguaglianza invece lo devi fornire tu ( consigliato anche quello di disuguaglianza: non è provviso in automatico ), perché, per esempio la std::list, non fornisce tale operatore come invece la std::string.
Infine vorrei farti notare come gli esempi siamo puramente didattici.
Ad esempio per copiare la lista in un altra (riprendendo l'operatore di assegnamento), ci sono modi meno complicati per farlo, a partire da:
codice:
componenti = a.componenti;