PROGRAMMIAMO
C++ - Funzioni friend
Programma per sommare due numeri complessi

Vogliamo ora scrivere un programma per fare la somma fra due numeri complessi. A tale scopo definiamo una classe complex, i cui attributi (dati private) sono la parte reale a e la parte immaginaria b di un numero complesso. La classe è inoltre dotata di un metodo set per assegnare un valore al numero complesso e di un metodo print per visualizzare sullo schermo il numero complesso. Infine abbiamo due costruttori (con lo stesso nome della classe) mediante i quali è possibile inizializzare un numero complesso col valore zero di default oppure con valori forniti dal programmatore:

class complex {
                private: double a, b;
                public:
                    complex() {a=0; b=0;}
                    complex(double x, double y){a=x; b=y;}
                    void set(double x, double y) {a=x; b=y;}
                    void print() {cout<<a<<"+j"<<b;}
            };

Si osservi come il secondo costruttore (quello con parametri) e il metodo set siano praticamente identici (a parte il fatto che il metodo è dichiarato di tipo void). La differenza è che il costruttore viene invocato al momento della dichiarazione di un oggetto complex, come per esempio in:

complex num(0.5,-1);

Il metodo set invece può essere applicato solo a un oggetto precedentemente dichiarato, allo scopo di modificarne il valore:

num.set(1.5, 0.2);

Tralasciamo la scrittura della parte di programma che si occupa di dichiarare e di acquisire due numeri complessi e concentriamoci invece sul problema di effettuare la somma. La somma di due numeri complessi num1 e num2 si ottiene sommando fra loro le due parti reali e le due parti immaginarie. Idealmente dunque si vorrebbe poter scrivere:

ris.a = num1.a + num2.a;
ris.b = num2.b + num2.b;

Tuttavia ciò non è possibile poiché a e b sono campi privati e dunque inaccessibili dall'esterno. Il problema non può essere risolto dichiarando un metodo somma interno alla classe complex. Infatti un tale metodo potrebbe accedere solo ai campi a e b dell'oggetto di appartenenza. Ma per fare una somma occorre accedere ai campi di due oggetti distinti (anche se della stessa classe complex) e questo non può essere fatto con un metodo interno a una classe.

Funzioni friend

Una funzione friend è una normale funzione C++, definita all'esterno delle classi. Non si tratta cioè di un metodo. Tuttavia, a differenza delle "normali" funzioni esterne, una funzione friend può accedere direttamente ai campi private di una classe.

Per autorizzare questo accesso (normalmente proibito) il prototipo della funzione dev'essere elencato fra i campi public della classe, accompagnato dalla parola chiave friend:

class complex {
                private: double a, b;
                public:
                    complex() {a=0; b=0;}
                    complex(double x, double y){a=x; b=y;}
                    void set(double x, double y) {a=x; b=y;}
                    void print() {cout<<a<<"+j"<<b;}
                    friend complex somma(complex, complex);
            };

Osserviamo con attenzione il prototipo della funzione somma: si tratta di una funzione che riceve come parametri due oggetti di tipo complex e ritorna un risultato ancora di tipo complex.

La definizione della funzione somma viene fatta all'esterno della classe, in fondo al file che contiene il programma main o in un file separato, come per qualsiasi normale funzione:

complex somma(complex n1, complex n2)
    {
    complex s;
    s.a = n1.a + n2.a;
    s.b = n1.b + n2.b;
    return s;
    }

Si presti attenzione al fatto che la parola chiave complex usata per denotare il valore di ritorno e il tipo degli argomenti della funzione non indica affatto l'appartenenza della funzione alla classe complex. In effetti la funzione non appartiene affatto a tale classe! Il legame particolare esistente fra questa funzione e la classe complex è invece dichiarato con l'attributo friend, che autorizza la funzione esterna all'accesso ai campi private della classe.

Si noti che la dichiarazione friend viene fatta all'interno della classe e non nella funzione. E' infatti la classe ad autorizzare la funzione all'accesso ai propri dati e non viceversa!

Per quanto riguarda la chiamata alla funzione somma, essa potrebbe essere la seguente:

int main(int argc, char *argv[])
{
complex x, y(1,2),r;

r = somma (x,y);

r.print();

system("PAUSE");
return EXIT_SUCCESS;
}

 

link precedente - successiva

Sito realizzato in base al template offerto da

http://www.graphixmania.it