Esercizio - Quiz su conversioni, constexpr, free store e downcasting (terzo appello 2021-22, quiz)
Quiz del terzo appello del corso di Laboratorio di Programmazione, Ing. Informatica UniPD, a.a. 2021-22 (30 giugno 2022, 90 minuti): dieci domande a quattro affermazioni vero/falso (giusta , sbagliata , non data ). Gli altri esercizi dell'appello: Esercizio - Helper function e la classe Book (terzo appello 2021-22, teoria), Esercizio - Confronto tra list e vector (terzo appello 2021-22, teoria), Esercizio - Costruttore di default, di copia e di spostamento (terzo appello 2021-22, teoria), Esercizio - Gerarchia MyPointer, MyUniquePointer e MySharedPointer (terzo appello 2021-22, programmazione).
1) La conversione di una variabile da int a bool:
2) In C++11, l'istruzione float x {3};:
| affermazione | V/F | motivo |
|---|---|---|
| Dà errore in fase di compilazione in quanto 3 non è rappresentato in forma decimale | F | il literal intero 3 si converte a float esattamente: nessun narrowing |
Inizializza la variabile x con il valore 3 |
V | x == 3.0f |
| Crea un array (C-style) di lunghezza 3 | F | le graffe qui sono l'inizializzatore, non la dimensione |
Dà errore in fase di compilazione se il codice prevede un cambio di valore della variabile x |
F | x non è const: si può cambiare |
3) In C++11, le keyword constexpr e const:
| affermazione | V/F | motivo |
|---|---|---|
| Sono equivalenti | F | constexpr richiede un valore noto in compilazione |
Rappresentano una variabile il cui valore costante è noto a tempo di compilazione per constexpr oppure al tempo di esecuzione per const |
V | è la definizione |
| Indicano che una variabile è costante e quindi non è possibile cambiarne il valore | V | entrambe |
Indicano che una variabile è costante ma nel caso di constexpr può cambiare durante l'esecuzione |
F | una constexpr non cambia mai |
4) Il passaggio di una variabile per riferimento a una funzione:
5) In C++, una classe:
6) I record di attivazione (RA):
7) Il free store:
8) I tipi che implementano una deep copy:
| affermazione | V/F | motivo |
|---|---|---|
| Copiano solo i puntatori e le reference, senza copiare i dati | F | è la shallow copy |
| Devono definire in modo esplicito il costruttore di copia e l'assegnamento in caso utilizzino una allocazione dinamica della memoria | V | quelli generati copierebbero il puntatore |
| Permettono la copia dei soli membri privati della classe | F | si copia tutto lo stato |
| Hanno un tempo di esecuzione più lento rispetto ai tipi che implementano la shallow copy | V | si duplicano i dati |
9) Il polimorfismo dinamico in C++:
10) Il downcasting in C++:
| affermazione | V/F | motivo |
|---|---|---|
| Rappresenta la conversione di una classe derivata in una classe base | F | è l'upcasting (sempre lecito, senza cast); il downcasting va dalla base alla derivata |
| È l'unico cast che effettua verifiche a run-time | V | dynamic_cast |
Viene effettuato tramite il dynamic_cast |
V | |
| Funziona con puntatori e reference | V | puntatori: nullptr se non lecito; reference: eccezione bad_cast |
Versione ripasso
- 1
intbool: F, V, F, F. Non sicura (narrowing), indipendente dall'architettura. C++ - tipi, variabili, espressioni e dichiarazioniun tipo definisce contenuto, intervallo di valori e operazioni; un oggetto è una regione di memoria con un tipo, il valore è la configurazione di bit letta in base al tipo, una variabile è un oggetto con un nome; inizializzazione (dare il primo valore) e assegnamento (cambiare il valore) sono diversi; le conversioni verso un tipo più capiente sono sicure, quelle verso un tipo meno capiente (narrowing, double->int, int->char) non lo sono e il compilatore le segnala di rado, ma la notazione con graffe {} le vieta; un'espressione calcola un valore da operandi e operatori, un lvalue è ciò che può stare a sinistra di =, constexpr vuole un valore noto in compilazione mentre const solo un valore che non cambia; gli operatori con side effect (++, --, +=) non vanno mischiati con altri usi della stessa variabile nella stessa espressione perché l'ordine di valutazione non è definito; una dichiarazione introduce un nome e un tipo, una definizione fornisce anche l'entità (memoria per una variabile, corpo per una funzione).C++ - tipi, variabili, espressioni e dichiarazioni →. - 2
float x {3};: F, V, F, F. Compila (3 è rappresentabile), inizializzaxa 3, non è un array,xnon èconst. - 3
constexpreconst: F, V, V, F. Non equivalenti:constexprnoto in compilazione,constanche a run-time; entrambe immutabili. - 4 Passaggio per riferimento: V, V, V, F.
&nel parametro, evita la copia, lettura/scrittura; non è un puntatore. C++ - funzioni, reference e passaggio dei parametriuna funzione ha parametri formali (0 o più, input) e un valore di ritorno (0 o 1, output); in C++ gli argomenti si passano per valore, cioè il parametro è una variabile locale inizializzata con una copia dell'argomento, e modificarla non cambia l'originale; per oggetti grandi (vector, immagini) la copia costa, e si passa per reference (T&), un alias dell'oggetto del chiamante che permette lettura e scrittura, oppure per const reference (const T&), alias in sola lettura verificata dal compilatore, che accetta anche literal (oggetto temporaneo); regola: valore per oggetti piccoli, const T& per grandi da non modificare, T& solo se la funzione deve davvero modificare o produrre più di un output; il passaggio converte l'argomento nel tipo del parametro come in un'inizializzazione e un cast esplicito (static_cast) rende visibile l'intenzione.C++ - funzioni, reference e passaggio dei parametri →. - 5 Classe: F, F, F, F. Può essere vuota, costruttore/distruttore generati, classi annidate lecite,
.per gli oggetti e->per i puntatori. - 6 RA: F, F, F, F. Nello stack, LIFO, dimensione variabile, contengono anche parametri e info di ritorno. C++ - chiamate a funzione e layout della memoriauna chiamata a funzione crea un record di attivazione (RA) con una copia dei parametri e le variabili locali, impilato nello stack (LIFO) e tolto all'uscita; la dimensione dipende dalle variabili locali e il tempo per inserirlo è costante; il processo ha cinque regioni di memoria: text (istruzioni, spesso read-only), initialized data (globali e statiche inizializzate), uninitialized data o BSS (globali e statiche non inizializzate, azzerate dal sistema), stack (RA) e heap (allocazione dinamica con new e delete); la durata (storage duration) di una variabile è diversa dallo scope: le globali e le static sono statiche (esistono per tutto il programma, inizializzate una volta), le locali sono automatiche (create all'entrata nel blocco, distrutte in ordine inverso all'uscita); le globali sono inizializzate prima del main ma l'ordine fra file diversi non è definito.C++ - chiamate a funzione e layout della memoria →.
- 7 Free store: F, V, V, V. Non per globali/locali;
new+ puntatori; heap dell'allocazione dinamica; la memoria allocata va liberata (altrimenti leak). - 8 Deep copy: F, V, F, V. Copia i dati; costruttore e assegnamento di copia espliciti con memoria dinamica; più lenta.
- 9 Polimorfismo dinamico: V, F, F, F. Ereditarietà + virtual; nessun risparmio di tempo; binding a run-time;
templateè del polimorfismo statico. C++ - polimorfismoPolimorfismo = abilità di associare comportamenti diversi a un'unica notazione generica. In C++ ci sono due forme principali: dinamico (ereditarietà più funzioni virtuali: vincolato dall'interfaccia della classe base, binding a run-time, permette collezioni eterogenee) e statico (template: svincolato, basta che i tipi abbiano la stessa sintassi, binding a tempo di compilazione, nessun costo a run-time ma una funzione per ogni tipo); il polimorfismo statico è lo strumento della programmazione generica. Anche l'overloading di funzioni e di operatori può essere visto come polimorfismo. Nella gerarchia si naviga con l'upcasting (implicito, sempre lecito) e il downcasting con dynamic_cast, l'unico cast con verifica a run-time: su un puntatore dà nullptr se non lecito, su un riferimento lancia bad_cast.C++ - polimorfismo →. - 10 Downcasting: F, V, V, V. Base derivata (l'altra direzione è upcasting);
dynamic_castè l'unico con verifiche a run-time; puntatori (nullptr) e reference (bad_cast). - Trappole:
.so/.dll,stack/heap,LIFO/FIFO, upcasting/downcasting, "per riferimento" confuso con "per puntatore".