back to top

Lโ€™overloading degli operatori in C++

Allโ€™atto della scrittura di un programma, anche molto semplice, ci si ritrova spesso a fare uso di funzioni. Per funzione si intende una parte di codice identificata da un nome e da una serie di parametri, che puรฒ essere richiamata in varie parti del programma.

Grazie allโ€™utilizzo di funzioni una stessa porzione di codice, utilizzata in piรน parti del programma, non deve essere riscritta piรน volte: sarร  infatti possibile scrivere la parte di codice in comune allโ€™interno di una funzione che potrร  essere richiamata quando necessario.

Pubblicitร 

Ad esempio si potrebbe definire una funzione stampa che visualizzi a video un certo numero di parametri di interesse e richiamarla poi con una semplice riga di codice (il nome della funzione) ogni volta che, nel programma principale, sia necessario avviare la visualizzazione di tali dati. Si migliora in tal modo sia lโ€™efficienza nella programmazione sia la leggibilitร  del codice.

Poniamo il caso perรฒ che si abbia a che fare con situazioni in cui si richiedono funzioni con funzionalitร  analoghe ma formalmente diverse.

Riprendiamo lโ€™esempio giร  esposto in precedenza: supponiamo che la nostra ipotetica funzione di stampa abbia lo scopo di stampare a video tutti i records estratti da una data tabella del nostro database; si ipotizzi, ancora, che in talune altre circostanza si desideri estrarre solo un numero determinato di records.

La soluzione piรน immediata sarebbe, senzโ€™altro, quella di scrivere due funzioni distinte, caratterizzate dunque da nomi diversi. Tale scelta non risulta perรฒ brillante dal punto di vista della leggibilitร  del codice, considerando che entrambe le funzioni svolgono, a livello concettuale, un ruolo del tutto analogo (estrarre dati dal database).

Sarebbe possibile anche sviluppare unโ€™unica funzione in grado di diversificare il proprio operato sulla base da due numeri interi passati in argomento: il primo indicherebbe il tipo di lavoro da svolgere (ad esempio 0 per stampare lโ€™intera tabella, 1 per stamparne una parte) ed il secondo il numero di righe da stampare in caso si stampi una parte della tabella (in caso contrario il valore del secondo parametro sarebbe ininfluente). Da un punto di vista funzionale questa soluzione รจ ineccepibile, ma da un punto di vista logico credo sia una soluzione concettualmente debole in quanto si ricorre a parametri fittizi e non necessari.

Allora perchรจ invece non sviluppare due funzioni identificate dallo stesso nome, una senza parametri (stampa lโ€™intera tabella) e una con un parametro intero (stampa un certo numero di righe)?

Tale possibilitร  รจ garantita dal meccanismo di overloading, che consente di derogare alla regola secondo cui una funzione debba essere identificata da un nome univoco, garantendo la possibilitร  di distinguere a quale delle omonime funzioni debba farsi ricorso semplicemente facendo riferimento al numero ed alla tipologia di parametri forniti.

Ad esempio ipotizziamo di scrivere un codice che contenga le seguenti definizioni di funzione:

int somma(int addendo1,int addendo2)
int somma(int addendo1,int addendo2,int addendo3)
Eโ€™ possibile definire separatamente il corpo delle due funzioni e richiamare quella piรน opportuna con una chiamata a somma accompagnata da due parametri interi per la prima funzione, tre per la seconda.

Definito in generale il meccanismo di overloading, รจ interessante notare come il linguaggio C++ offra unโ€™ulteriore interessante opportunitร : lโ€™overloading degli operatori.

Eโ€™ possibile cioรจ associare allโ€™utilizzo di un operatore, se legato ad operazioni relative ad una certa classe, una particolare sequenza di istruzioni definita nel corpo della classe stessa.

Ad esempio, se si volesse progettare una classe Counter con funzioni di contatore potrebbe essere utile (oltre alla definizione, ad esempio, dei costruttori, del distruttore, del costruttore di copia e di un metodo per incrementare il valore del dato membro della classe) anche far sรฌ che tale incremento possa essere realizzato tramite lโ€™uso dellโ€™operatore unario ++. In altre parole si vuol rendere possibile e corretta, nel programma principale, una sequenza del tipo:

Counter count=new Counter(0);
count++;
con corrispondente incremento del valore del dato membro val di count.

Per ottenere tale risultato รจ necessario dichiarare allโ€™interno dei metodi della classe Counter un particolare metodo denominato, in questo caso, void operator++, ad esempio in questo modo:

class Counter{
unsigned short val;
...
public:
...
void operator++()
}
A livello di implementazione, seguirร  la descrizione delle azioni da associare allโ€™operatore ++:
void Counter::operator++()
{
val++;
}
Lโ€™overloading degli operatori risulta utile soprattutto nel caso in cui lโ€™utilizzo di un operatore risulti particolarmente intuitivo per unโ€™operazione di uso comune tra oggetti del tipo che si sta definendo in fase di progettazione della classe (ad esempio puรฒ essere di grande praticitร  lโ€™overloading dellโ€™operatore binario + per la concatenazione di stringhe di testo o simile).

Questa possibilitร  รจ utile anche qualora si desideri sovraccaricare gli operatori matematici al fine di mantenere il loro significato comune anche in contesti matematici differenti. Si pensi, ad esempio, allโ€™utilizzo dellโ€™operatore + per lavorare con i vettori (si pensi, per semplicitร , a vettori costituiti da due soli elementi), utilizzo che puรฒ essere opportunamente ridefinito grazie allโ€™overloading, facendo sรฌ che la somma di due vettori abbia come risultato un vettore con componenti uguali ciascuna alla somma delle componenti dei due addendi. Ad esempio:

class Vector{
int x;
int y;
...
public:
...
Vector operator +(Vector v);
}
...
Vector Vector::operator +(Vector v)
{
Vector temp=new Vector();
temp.x=this.x+v.getx();
temp.y=this.y+v.gety();
return temp;
}

Altri contenuti interessanti

Pubblicitร 

Leggi anche...

Vibe Coding: cosโ€™รจ, come funziona e quali sono i migliori strumenti AI per programmare

Immagina di poter scrivere software senza dover digitare una...

I migliori libri per imparare a programmare in Python

Imparare a programmare in Python รจ un passo fondamentale...

Il file manifest.json: cosโ€™รจ e a cosa serve

Il file manifest.json รจ un componente chiave nelle applicazioni web moderne,...

Java: cosโ€™รจ e a cosa serve lโ€™operatore modulo (%)

In Java, l'operatore modulo รจ rappresentato dal simbolo "%"...

Radice quadrata in C: vediamo come calcolarla in diversi modi

La radice quadrata รจ un'operazione matematica piuttosto comune (in...

Sperimentare la sequenza di Collatz in C++

Vediamo come verificare la congettura di Collatz con C++....
Pubblicitร