appunti3s:costruttore
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
appunti3s:costruttore [2017/07/09 12:33] – profpro | appunti3s:costruttore [2020/06/08 22:19] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | < < indice degli [[appunti3s: | ||
+ | |||
+ | ===== Costruttore ===== | ||
+ | Nel linguaggio C++ si utilizzano dei " | ||
+ | Per capire cosa sia una classe e una funzione membro si deve __prima__ leggere | ||
+ | |||
+ | * [[appunti3s: | ||
+ | * [[appunti3s: | ||
+ | |||
+ | |||
+ | Dato che la classe è un nuovo tipo di dato, essa deve descrivere, oltre alla struttura dei dati e delle sue funzioni membro, anche come (1)// | ||
+ | |||
+ | Il // | ||
+ | Il compilatore permette di usare un costruttore di default (predefinito), | ||
+ | |||
+ | ====Dichiarazione==== | ||
+ | |||
+ | La // | ||
+ | - non restituisce nulla (neppure void); | ||
+ | - possiede lo stesso nome della classe a cui appartiene. | ||
+ | |||
+ | Codice della chiamata del costruttore predefinito, | ||
+ | < | ||
+ | ContoCorrente conto1; | ||
+ | </ | ||
+ | |||
+ | Il codice appena visto deve essere inserito nel contesto di questo esempio: [[appunti3s: | ||
+ | |||
+ | Codice della chiamata di un altro costruttore, | ||
+ | < | ||
+ | ContoCorrente conto2(90.00); | ||
+ | </ | ||
+ | |||
+ | ====Definizione==== | ||
+ | Il costruttore costruisce l' | ||
+ | < | ||
+ | ContoCorrente:: | ||
+ | { | ||
+ | | ||
+ | // questo metodo è inefficiente :( | ||
+ | // resto del codice... | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===La lista di inizializzazione dei membri=== | ||
+ | C'è un modo molto più comodo ed efficiente di inizializzare i membri di un oggetto mettendo anche in evidenza l' | ||
+ | |||
+ | < | ||
+ | ContoCorrente:: | ||
+ | : mSaldo(saldo) | ||
+ | { | ||
+ | // resto del codice... | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | Questa tecnica, alternativa alle assegnazioni, | ||
+ | * per i membri costanti, | ||
+ | * per tutti i membri che non usano il costruttore predefinito (oggetti) | ||
+ | * per tutti i reference. | ||
+ | |||
+ | Usandola sempre si evita di sbagliare! | ||
+ | |||
+ | Al momento della chiamata del costruttore, | ||
+ | |||
+ | ===== Funzioni membro predefinite ===== | ||
+ | Sono funzioni che esistono sempre, anche se il programmatore non le definisce. In questo modo si ottiene la garanzia che alcune operazioni di uso frequente siano possibili. Si tratta di operazioni necessarie all' | ||
+ | * costruttore minimo < | ||
+ | * distruttore | ||
+ | * costruttore di copia< | ||
+ | * operazione di assegnazione con copia < | ||
+ | |||
+ | Oltre ad essere operazioni frequenti, si tratta anche di operazioni delicate, che spesso il programmatore deve ri-definire, | ||
+ | * si passa un oggetto per valore ad una funzione | ||
+ | * una funzione deve restituire un oggetto | ||
+ | * una funzione deve lanciare un oggetto come eccezione (throw) | ||
+ | Tutte le funzioni membro viste, essendo predefinite, | ||
+ | |||
+ | ==== Costruttore predefinito ==== | ||
+ | |||
+ | Il costruttore predefinito è usato per l' | ||
+ | < | ||
+ | NomeClasse a; // costruttore predefinito : privo di argomenti! | ||
+ | </ | ||
+ | |||
+ | È utile definirlo quando si crea una nuova classe in una libreria, perché chi utilizzerà la libreria potrebbe creare un oggetto senza fornire adeguati elementi di inizializzazione ed un eventuale costruttore predefinito fornirebbe una certa garanzia sul contenuto del nuovo oggetto. | ||
+ | Inoltre il costruttore predefinito può essere riutilizzato all' | ||
+ | * // | ||
+ | * < | ||
+ | * definizione | ||
+ | * < | ||
+ | : // segue la lista di inizializzazione... | ||
+ | {}</ | ||
+ | |||
+ | ==== Distruttore predefinito ==== | ||
+ | |||
+ | < | ||
+ | È molto simile al precedente e viene invocato automaticamente quando un oggetto precedentemente creato esce dal suo campo di visibilità o deallocato con delete. Quindi a maggior ragione è importante che esista sempre. Va ricordato che il distruttore non ha mai nessun argomento. | ||
+ | * // | ||
+ | * < | ||
+ | * definizione | ||
+ | * < | ||
+ | | ||
+ | ==== Costruttore di copia predefinito ==== | ||
+ | * Il costruttore predefinito è usato per l' | ||
+ | * Anche il costruttore di copia predefinito inizializza (usando i dati membro di un altro oggetto esistente). | ||
+ | < | ||
+ | NomeClasse a(); // costruttore predefinito | ||
+ | NomeClasse b = a; // costruttore di copia predefinito | ||
+ | </ | ||
+ | Nel caso in cui un oggetto (a) contiene almeno un puntatore ad un altro oggetto %%(c)%%, debba essere duplicato (b), il costruttore di copia predefinito effettuerebbe solo una copia dei valori contenuti nei dati membro e verrebbero solo copiati gli indirizzi contenuti nei puntatori. | ||
+ | Esisterebbero due nuovi oggetti (a e b), ma il secondo contiene dei puntatori allo stesso oggetto %%(c)%% a cui punta il primo e modificando il contenuto del secondo (b) si rischia di modificare il contenuto del primo (a). | ||
+ | Per questo motivo il costruttore di copia deve essere ridefinito nel caso che la classe abbia come membri: reference, costanti o altri oggetti di tipo classe. Questo perché tutti questi tipi non sono mai inizializzate automaticamente, | ||
+ | |||
+ | * // | ||
+ | * < | ||
+ | * definizione | ||
+ | * < | ||
+ | : // segue la lista di inizializzazione... | ||
+ | {}</ | ||
+ | Il costruttore di copia viene usato dal programma sia nel passaggio di parametri __per valore__ sia nel momento della restituzione di un valore alla funzione chiamante. Perciç questo costruttore dovrebbe essere personalizzato dal programmatore. | ||
+ | Durante il passaggio di parametri __per valore__ ad una funzione, il programma deve usare il costruttore di copia predefinito per poter realizzare una copia degli oggetti passati. | ||
+ | È bene comunque ricordare che in alternativa al passaggio per valore si potrebbe passare l' | ||
+ | ==== Operatore assegnazione di copia predefinito ==== | ||
+ | * Il costruttore predefinito è usato per l' | ||
+ | * Anche il costruttore di copia predefinito inizializza (usando i dati membro di un altro oggetto esistente). | ||
+ | * L' | ||
+ | |||
+ | < | ||
+ | NomeClasse a(); // costruttore predefinito | ||
+ | NomeClasse b = a; // costruttore di copia predefinito | ||
+ | NomeClasse c; | ||
+ | c = b; // | ||
+ | </ | ||
+ | Nonostante vi sia una differenza sostanziale, | ||
+ | |||
+ | * // | ||
+ | * < | ||
+ | * // | ||
+ | * < | ||
+ | { | ||
+ | //... | ||
+ | | ||
+ | }</ | ||
+ | |
appunti3s/costruttore.txt · Last modified: 2020/06/08 22:19 by 127.0.0.1