• Regolamento Macrocategoria DEV
    Prima di aprire un topic nella Macrocategoria DEV, è bene leggerne il suo regolamento. Sei un'azienda o un hosting/provider? Qui sono anche contenute informazioni per collaborare con Sciax2 ed ottenere l'accredito nella nostra community!

Guida Novità dal C++11

sant0

Utente Esperto
Autore del topic
1 Settembre 2014
1.345
124
Miglior risposta
0
So che in qualche modo si può considerare tardi pubblicare una guida con le novità approdate in C++11 (o C++0x) ma, dato che dalla versione C++14 e C++17 non c'è poi tanto altro di nuovo, mi sembrava giusto parlarne e magari puntualizzare qualche novità del 14 e del 17.

Dal 2011, tutte le versione di C++, sono considerate C++ moderno (anche quelle di quest'anno); tutte queste modifiche portano uno dei linguaggi di programmazioni più famosi al mondo ad un livello più alto. Infatti, prima del 2011, anche per utilizzare il multithreading, bisognava installare librerie di terze parti. Voglio precisare che in questa guida accennerò ai threads, ma che non ne parlerò in particolare, dato che perderei ore a farlo.

Tipo auto
Eccovi un nuovo tipo di dato, utilissimo in molti casi dato che sarà il compilatore a capire e tradurre il dato nel giusto tipo. È ovvio che bisogna inizializzarla la variabile, dato che, espressioni del tipo auto x;, non avranno un senso. Eccovi alcuni esempi:
C++:
Perfavore, Entra oppure Registrati per vedere i codici!

decltype
Con decltype è possibile identificare il tipo di un'entità: decltype(entità).
C++:
Perfavore, Entra oppure Registrati per vedere i codici!

Ciclo for basato su sequenza
Ereditato in qualche modo da oramai tutti i linguaggi di programmazioni, il nuovo for, permette di iterare senza il bisogno di sapere il numero di elementi.
C++:
Perfavore, Entra oppure Registrati per vedere i codici!

funzioni lambda
Sempre dal C++11 sono disponibili le cosiddette funzioni incognite, già disponibili in modo simile in Python. È composta da: clausola di acquisizione, elenco parametri, specifica modificabile (mutable), specificazione eccezione (throw), ritorno a valore, corpo classe. Tranne la clausola e il corpo classe, gli altri elementi sono facoltativi:
[=] (int x) mutable throw() -> int { return x; }(42);

C++:
Perfavore, Entra oppure Registrati per vedere i codici!

La clausola di acquisizione è quella tra le parentesi quadre [ ] e se è vuota indica che il corpo dell'espressione lambda non accede a variabili nell'ambito che lo contiene, altrimenti se contiene &, significa che tutte le variabile vengono acquisite per riferimento, mentre = indica che esse vengono acquisite per valore.
C++:
Perfavore, Entra oppure Registrati per vedere i codici!

Un altro esempio, magari più utile di quelli fatti sopra, può essere:
C++:
Perfavore, Entra oppure Registrati per vedere i codici!

Dato il complesso argomento vi rimando alla guida di Stroustrup
Perfavore, Entra oppure Registrati per vedere i Link!
.

Dichiarazione funzioni

Ok, magari questa novità non la utilizza quasi nessuno - io in primis - ma, visto che per alcuni può essere migliore, vi spiego l'unico motivo per cui io consiglio di usarla: nomi delle funzioni nella stessa linea.
auto nome_funzione(params) -> valore_ritorno {
corpo funzione
}

ecco un esempio:
C++:
Perfavore, Entra oppure Registrati per vedere i codici!

Inizializzazione lista

Un vettore (o una lista, una map, una nostra classe...) vi si può inizializzare in modo più sintetico:
C++:
Perfavore, Entra oppure Registrati per vedere i codici!
Questo perché avviene? Perché nel costruttore della classe, i parametri vengono passati dalla classe
Perfavore, Entra oppure Registrati per vedere i Link!
.

Tuple

Per chi conosce il Python, sa di cosa parlo: le tuple sono una lista immutabile; in C++ però, immutabili, non sono. Inizializzarle non è semplice, o meglio, vi si possono trovare modi diversi per farlo. Ad esempio, vogliamo creare una lista composta da username, anni su Sciax2, numero fortunato:
C++:
Perfavore, Entra oppure Registrati per vedere i codici!

Per visualizzarlo vi si fa ricorso al metodo std::get (anch'esso dentro al file tuple):
C++:
Perfavore, Entra oppure Registrati per vedere i codici!

L'ultimo modo di utilizzare std::get può risultare scomodo (e in realtà genera anche un errore nella compilazione) quando vi si ha più di un valore dello stesso tipo.

Costruttore default e delete
Dal C++11 un costruttore di una classe (o di una struct) può essere identificato come default. Identificare un costruttore come default aumenta le performance, ecco perché è consigliato usarlo.
C++:
Perfavore, Entra oppure Registrati per vedere i codici!
Con la parola chiave delete si identifica un costruttore che non bisogna utilizzare e, se utilizzato, genererà per l'appunto, un errore. Il seguente codice darà il seguente errore: use of deleted function 'myclass::myclass(const myclass&)'.
C++:
Perfavore, Entra oppure Registrati per vedere i codici!

Costruttore explicit

In genere il compilatore si occupa di convertire implicitamente gli oggetti per risolvere i problemi che potrebbero causare i parametri di una funzione. Se dichiarassimo un costruttore di tipo explicit, saremmo costretti a sistemare il problema, occupandoci noi stessi di creare la conversione.
C++:
Perfavore, Entra oppure Registrati per vedere i codici!

C++:
Perfavore, Entra oppure Registrati per vedere i codici!

Override

L'identificativo override permette di specificare le funzione virtuali ereditate da cui è possibile fare l'override.
C++:
Perfavore, Entra oppure Registrati per vedere i codici!

Final

Con l'identificativo final è possibile specificare quali metodi, classi o structs non possono essere ereditati (o da cui è possibile fare l'override).
C++:
Perfavore, Entra oppure Registrati per vedere i codici!

Enum class
Un piccolo aggiornamento all'enumerazioni (enum). Le enum class richiamano molto la sintassi delle classi, usando per l'appunto, l'operatore di scope.
C++:
Perfavore, Entra oppure Registrati per vedere i codici!

C++:
Perfavore, Entra oppure Registrati per vedere i codici!

constexpr
Le espressioni costanti nel C++11 permettono di avere un programma più ottimizzato, dato che le operazioni vengono calcolate in fase di compilazione e non in esecuzione. L'esempio più intuitivo è quello della successione di fibonacci.
C++:
Perfavore, Entra oppure Registrati per vedere i codici!
C++:
Perfavore, Entra oppure Registrati per vedere i codici!
Nel primo caso, il tempo di esecuzione è di ~ 0.017s. Il secondo impiega ~ 0.004s.

Le funzioni dichiarate come constexpr hanno delle restrizioni:

  • possono fare una sola espressione di return, infatti nel caso di prima vi si fa uso della ricorsione;
  • possono richiamare solo altre funzioni constexpr;
  • non possono non avere nessun tipo di ritorno (void);
  • non possono essere virtuali;
  • possono avere direttive/dichiarazione con using;
  • non possono avere costrutti goto;
  • dal C++14 si possono avere i costrutti try/catch;
  • una variabile marcata come constexpr è al contempo anche const.
Le funzioni dichiarate come constexpr possono comunque essere chiamate in fase runtime:
C++:
Perfavore, Entra oppure Registrati per vedere i codici!
 
Ultima modifica:
  • Like
Reactions: Matheeus and Kaost
# Aggiunti costruttore default, delete ed explicit
# Aggiunti identificativi override e final

6/11
# Aggiunte enum class

7/11
# Aggiunto identificativo constexpr
# Aggiunto identificativo decltype (dopo Tipo auto)
 
Ultima modifica: