Skip to content

Modificatori e Tipi di Ritorno

Le funzioni in C++ servono a incapsulare la logica.

“Functions should do one thing. They should do it well. They should do it only.” — Robert C. Martin

In questo capitolo scenderemo nei meandri più tecnici delle funzioni e dei concetti funzionali introdotti col C++ moderno.

Modificatori di Funzione (Prefix e Suffix)

Section titled “Modificatori di Funzione (Prefix e Suffix)”

La firma di una funzione in C++ può essere adornata da molteplici keyword. Alcune vanno prima del tipo di ritorno (prefix), altre in coda (suffix). Non c’è una logica linguistica assoluta dietro questa suddivisione, è unicamente frutto dell’evoluzione storica del linguaggio.

Abbiamo già incontrato:

  • static: Se usato su funzioni libere, indica un Internal Linkage (la funzione è visibile solo all’interno del suo file .cpp). Se usato sui metodi di classe, slega il metodo dall’istanza.
  • virtual: Consente al metodo di essere sovrascritto dalle classi figlie.
  • constexpr: Comunica al compilatore di calcolare la funzione a tempo di compilazione.

Un modificatore critico è inline. Richiedere che una funzione sia inline suggerisce al compilatore di evitare la vera chiamata a funzione a runtime (che implicherebbe l’uso dei registri, lo stack, il salto e il ritorno), e di letteralmente copia-incollare le istruzioni interne della funzione direttamente nei punti in cui viene invocata nel binario. Migliora le performance sacrificando le dimensioni del file compilato. (I compilatori moderni lo fanno in automatico, ma usarlo negli Header previene errori di definizione multipla).

Abbiamo già visto const (la funzione non altera i campi della classe) e noexcept (non lancerà eccezioni). Ne aggiungiamo due:

  • final: Esattamente l’opposto di virtual. Blocca definitivamente l’ereditarietà di quel metodo. Nessuna classe figlia potrà mai più sovrascriverlo. Questo agevola la Devirtualization (il compilatore rimuove il sovraccarico dinamico sapendo che la catena si è chiusa).
  • volatile: Usato sui metodi, si comporta come const: significa che questo metodo può essere legittimamente invocato su un’istanza dell’oggetto dichiarata come volatile (e quindi non sarà ottimizzata via).

Nelle funzioni ordinarie sappiamo già quale tipo vogliamo restituire. Tuttavia, quando costruiamo Funzioni Template generiche, il tipo di ritorno può dipendere interamente dalla “matematica” fatta tra i due parametri astratti!

Come fai a dichiarare il tipo di ritorno di add(T1 a, T2 b) se non sai se T1 è un intero e T2 un double? Usi auto. Il compilatore dedurrà da sé il risultato.

Storicamente, si usava (e si usa in metaprogrammazione fitta) il potente strumento decltype(espressione). Restituisce il tipo esatto risultante dall’espressione passata tra parentesi senza valutarla.