new e delete (3) - la dimensione dello heap non e` infinita
- l’allocazione con new può fallire, nel qual caso new restituisce un puntatore nullo o suscita un’eccezione. Nel caso di allocazione di memoria importante bisogna verificare che l’operazione abbia avuto successo prima di usare il puntatore
- ogni oggetto creato con new deve essere distrutto con delete, ogni oggetto creato con new [] deve essere distrutto con delete [] , queste forme NON sono intercambiabili
In C++ esistono conversioni esplicite ed implicite. - Le conversioni implicite (e.g. intfloat) nelle espressioni aritmetiche, nel passare i parametri ad una funzione o nel ritornare un valore da una funzione rendono il meccanismo di conversione molto conveniente ma anche potenzialmente pericoloso (errori a run time)
Regole di conversione e cast (2) Ogni genere di puntatore può essere convertito in un puntatore generico a void Al contrario di quanto avviene in C, un puntatore generico non è compatibile con un puntatore di tipo arbitrario ma richiede un cast esplicito Ogni puntatore puo` essere inizializzato a 0 senza bisogno di un cast esplicito. In C++ usare 0 e non NULL per i puntatori!
Casting in ANSI C++ Data la complessità delle operazioni di casting in C++ nuovi operatori di casting sono stati aggiunti a quelli già esistenti in C Esiste anche un dynamic_cast, utilizzato per riconoscere il tipo di un oggetto a run-time (RTTI)
Funzioni In C++ le funzioni sono caratterizzate da un nome, dal tipo della variabile ritornata e da una lista di parametri (opzionali) Il valore ritornato deve essere compatibile, a meno di conversione esplicita, con il tipo della funzione
Funzioni (2)
Prototipi delle funzioni Prima di essere usata, una funzione deve essere dichiarata (nel file che la usa) I prototipi rendono le funzioni in C++ “type safe”, nel senso che i valori reali degli argomenti vengono all’occorrenza convertiti nei tipi formali specificati dal prototipo
Call-by-Reference L’uso dei riferimenti permette ad una funzione di modificare il valore dei suoi argomenti - Per ragioni di efficenza, oggetti di grandi dimensioni (in termini di memoria) vengono normalmente passati “by reference”.
- Per evitare che possano essere modificati dalla funzione, il riferimento viene definito const
Funzioni inline La keyword inline suggerisce al compilatore che ogni chiamata alla funzione deve essere convertita in codice eseguibile (la definizione della funzione viene sostituita alla chiamata dovunque nell codice) Le funzioni inline vengono usate per ragioni di efficienza e (per non sovraccaricare il compilatore) devono essere semplici Il compilatore può decidere autonomamente (per esempio se la funzione è troppo lunga) di ignorare la direttiva inline
Argomenti di default Ad ogni parametro di una funzione può essere assegnato un valore di default. Questo permette di chiamare la funzione tralasciando quei parametri il cui valore di default risulta appropriato Solo ai parametri più a destra nella calling sequence può essere dato un default.
Overloading Funzioni diverse possono avere lo stesso nome La funzione che viene chiamata è scelta dal compilatore in base al tipo di ritorno ed al numero e tipo degli argomenti
Overloading (2) La lista dei tipi degli argomenti di una funzione è chiamata signature Il tipo ritornato dalla funzione non fa parte della signature, mentre il numero e l’ordine degli argomenti è cruciale
L’algoritmo di selezione L’utente può sempre utilizzare una conversione forzata (type cast) per ottenere una corrispondenza Il compilatore segnala tutti i casi in cui esiste ambiguità
Funzioni esterne Si possono chiamare funzioni FORTRAN da C++: SUBROUTINE HBOOK1(ID, TITLE, NBIN, MIN, MAX, OPT) SUBROUTINE HFILL(ID,X, Y, WEIGHT) extern “C” void hbook1_(int&, char*, int&, float&, float&, float&, int); extern “C” void hfill_(int&, float&, float&, float&); ... hbook1_(100, title, ……) // BUS ERROR!!! (il FORTRAN passa
|