Beh io credo che in C++ siano stati introdotti i riferimenti proprio per facilitare la gestione dei passaggi per riferimento degli argomenti ad una funzione... in effetti può non essere immediato entrare nell'ordine di idee che anteponendo una & ai nomi dei parametri nel prototipo di una funzione, questi poi sono dei puntatori, ma una volta fattaci l'abitudine può diventare relativamente più semplice leggere e scrivere il codice.
Sono io che sono ignorante o effettivamente la 'vecchia maniera' era meglio? Se mi sbaglio potete farmi degli esempi in cui questo nuovo modo di scrivere aumenta la chiarezza di un programma?
Se vuoi un esempio di come questo possa essere di aiuto in alcuni casi, considera questo codice che è un'implementazione (non mia! Anzi scusa se è un po' disordinata) dell'algoritmo LCS
codice:
#include <iostream>
#include <string>
using namespace std;
string Lcs(string X, string Y, int **C, char **B)
{
int X_len=X.length()+1; int Y_len=Y.length()+1;
int i,j;
string lcs=" ";
C=new int*[X_len];
B=new char*[X_len];
for(i=0; i<X_len; i++)
{
C[i]=new int[Y_len];
B[i]=new char[Y_len];
}
B[0][0]='\\';
for(i=1; i<X_len; i++)
{
for(j=1; j<Y_len; j++)
{
if(X[i-1]==Y[j-1])
{C[i][j] = 1 + C[i-1][j-1]; B[i][j] = '\\';}
else if(C[i-1][j] >= C[i][j-1])
{ C[i][j] = C[i-1][j]; B[i][j] = '|';}
else {C[i][j]=C[i][j-1]; B[i][j] = '-';}
}
}
for(i = 1; i< Y_len; i++) // Costruisce la stringa di lunghezza LCS
{ if(C[X_len-1][i] > C[X_len-1][i-1]) lcs = lcs + Y[i-1];}
return lcs;
}
int main(){
string X = "FRANCESCO"; string Y = "FWANCICO";
int X_len = X.length() + 1; int Y_len = Y.length() + 1; int i,j;
int **C=NULL; char **B=NULL;
string lcs = Lcs(X,Y,C,B);
// cout << "LCS = " << C[X_len-1][Y_len-1] << lcs <<endl<< endl << " ";
// Stampa la matrice C che contiene le soluzioni dei vari sottoproblemi
for(i = 0; i< Y_len;i++) cout << " " << Y[i];
for (i =0; i< X_len; i++){
cout << endl;
if (i >= 1) cout << X[i-1] << " ";
else cout << " ";
for (j = 0; j< Y_len; j++) { cout << C[i][j] << " "; }
}
cout << endl << endl << " ";
// Stampa la matrice B che contiene i percorsi dei vari sottoproblemi
for(i = 0; i< Y_len; i++) cout << " " << Y[i];
for (i =0; i< X_len; i++){
cout << endl;
if (i >= 1) cout << X[i-1] << " ";
else cout << " ";
for (j = 0; j< Y_len; j++) {cout << B[i][j] << " ";}
}
cout << endl;
if (C != NULL) // Delloca le matrici
{
for (i=0;i<X.length();i++) { delete C[i]; delete B[i];}
delete C; delete B;
}
return 0;
}
al di là di quello che l'algoritmo deve fare, come puoi vedere nel main() viene allocato spazio per due matrici che poi vengono passate alla funzione Lcs che dovrà lavorarci sopra. Ora, scritto in questo modo, il programma non funziona perché le matrici sono passata per valore alla funzione, non per riferimento... quindi le modifiche che apporta la funzione alle matrici sono locali ad essa e non visibili in main().
Come risolvere? Dovremmo passare le matrici per riferimento, quindi dichiarare passare un puntatore a queste... ma C e B sono già puntatori a puntatori, quindi dovremmo ricorrere a puntatori a puntatori a puntatori... ^^ (ovviamente si potrebbe anche semplificare il tutto rappresentando le matrici con un puntatore singolo e ricorrendo poi alla mappa di memorizzazione ma vabbè...)
Ecco che invece basterà semplicemente sostituire l'intestazione della funzione con
codice:
string Lcs(string X, string Y, int **&C, char **&B)
senza apportare modifiche al suo corpo, e il programma funziona correttamente.