Costanti vere dentro le classi
Poiche` gli attributi const altro non sono che attributi a sola
lettura, ma che vanno inizializzati tramite lista di inizializzazione, e` chiaro
che non e` possibile scrivere codice simile:
class BadArray {
public:
/* ... */
private:
const int Size;
char String[Size]; // Errore!
};
perche` non si puo` stabilire a tempo di compilazione il valore di Size .
Le possibili soluzioni al problema sono due.
La soluzione tradizionale viene dalla keyword enum ; se ricordate
bene, e` possibile stabilire quali valori interi associare alle costanti che
appaiono tra parentesi graffe al fine di rappresentarle.
Nel nostro caso dunque la soluzione e`:
class Array {
public:
/* ... */
private:
enum { Size = 20 };
char String[Size]; // Ok!
};
Si osservi che la keyword enum non e` seguita da un identificatore,
ma direttamente dalla parentesi graffa; il motivo e` semplice: non ci interessava
definire un tipo enumerato, ma disporre di una costante, e quindi abbiamo creato
una enumerazione anonima il cui unico effetto in questo caso e`
quello di creare una associazione nome-valore all'interno della
tabella dei simboli del compilatore.
Questa soluzione, pur risolvendo il nostro problema, soffre di una grave limitazione:
possiamo avere solo costanti intere. Una soluzione definitiva al nostro problema
la si trova utilizzando contemporaneamente le keyword static e
const :
class Array {
public:
/* ... */
private:
static const int Size = 20;
char String[Size]; // Ok!
};
Essendo static , Size viene inizializzata prima della
creazione di una qualunque istanza della classe ed essendo const
il suo valore non puo` essere modificato e risulta quindi prefissato gia` a
compile time. Le costanti dichiarate in questo modo possono avere tipo qualsiasi
e in questo caso il compilatore puo` non allocare alcuna memoria per esse, si
ricordi solo che non tutti i compilatori potrebbero accettare l'inizializzazione
della costante nella dichiarazione di classe, in questo caso e` sempre possibile
utilizzare il metodo visto per gli attributi static:
class Array {
public:
/* ... */
private:
static const int Size;
char String[Size]; // Ok!
};
const int Array::Size = 20;
Anche in questo caso non bisogna riutilizzare static in fase di
inizializzazione.
|