In quel caso forse funziona male perchè ci sono due volte 2(e cancellerebbe il primo penso, ma facciamo finta che non ci siano doppioni)...
Deduco non l'abbia scritto tu allora quel codice!
In ogni caso il problema del metodo elimina si trova effettivamente nel frammento di codice da te indicato e che si riferisce al caso in cui il primo elemento della lista è uguale a val.
Il problema è che all'uscita da quell'ifelse, il puntatore this (che coincide con il puntatore testa con cui è stato richiamato il metodo elimina dal main) punterà all'area di memoria deallocata in cui era memorizzato il primo elemento della lista. L'area a cui puntava testa, ritornata disponibile in seguito al delete, potrebbe essere sovrascritta con la conseguenza che qualsiasi utilizzo del puntatore testa genererà un risultato imprevedibile.
Il puntatore P utilizzato nel metodo, che punta correttamente al secondo elemento della lista, all'uscita dalla funzione cesserà di esistere risultando quindi inutilizzabile. In questo modo ogni riferimento certo alla nostra lista andrà perso.
L'ifelse andrebbe quindi corretto nel seguente modo:
else if(a == val)
{
prec = this;
this = ptr;
delete prec;
}
peccato però che this sia un puntatore costante e come tale non può essere modificato...
L'unica soluzione che mi viene in mente è quella di convertire il metodo elimina in una funzione esterna alla classe come già ti avevo suggerito di fare nel mio precedente post.