CV sta per Constant-Volatile. La dichiarazione di un oggetto che non è preceduto da const e/o volatile è di tipo cv-non qualificato. D'altra parte, la dichiarazione di un oggetto che è preceduto da const e/o volatile è un tipo qualificato cv. Se un oggetto viene dichiarato const, il valore nella sua posizione non può essere modificato. Una variabile volatile è una variabile il cui valore è sotto l'influenza del programmatore e quindi non può essere modificato dal compilatore.Gli identificatori di classe di archiviazione si riferiscono alla vita, al luogo e al modo in cui esiste un tipo. Gli identificatori di classe di archiviazione sono statici, mutabili, thread_local ed extern.
Questo articolo spiega i qualificatori C++ e gli identificatori di classi di archiviazione. Pertanto, alcune conoscenze preliminari in C++ sono utili per apprezzare davvero l'articolo.
Contenuto dell'articolo:
- Qualificazioni
- Specificatori della classe di archiviazione
- Conclusione
Qualificazioni:
cost
Un oggetto dichiarato costante è un oggetto la cui memorizzazione (posizione) il cui valore non può essere modificato. Ad esempio, nella dichiarazione:
int const theInt = 5;Il valore di 5 nella memoria per l'Int non può essere modificato.
volatile
Considera la seguente affermazione:
int portVal = 26904873;I compilatori a volte interferiscono con il valore di una variabile con la speranza di ottimizzare il programma. Il compilatore può mantenere il valore di una variabile come costante quando non dovrebbe essere costante. I valori degli oggetti che hanno a che fare con le porte IO mappate in memoria o le routine di servizio di interrupt dei dispositivi periferici possono essere interferiti dal compilatore. Per prevenire tale interferenza, rendere la variabile volatile, come:
int volatile portVal;portVal = 26904873;
o come:
int volatile portVal = 26904873;
Combinando const e volatile:
const e volatile possono verificarsi in un'istruzione come segue:
int const volatile portVal = 26904873;cv-qualificazioni
Una variabile preceduta da const e/o volatile è un tipo qualificato cv. Una variabile non preceduta da const o volatile o entrambi è di tipo cv-non qualificato.
Ordinazione:
Un tipo può essere più qualificato cv di un altro:
- Nessun qualificatore cv è inferiore a un qualificatore const
- Nessun qualificatore cv è anche meno di un qualificatore volatile
- Nessun qualificatore cv è inferiore a un qualificatore const-volatile
- il qualificatore const è minore di un qualificatore const volatile
- il qualificatore volatile è minore di un qualificatore const-volatile
Non è stato ancora concluso se const e volatile sono dello stesso rango.
Array e oggetto istanziato:
Quando un array viene dichiarato costante, come nell'istruzione seguente, significa che il valore di ogni elemento dell'array non può essere modificato:
const char arr[] = 'a', 'b', 'c', 'd';Che si tratti di 'a', 'b', 'c' o 'd', non può comunque essere cambiato con qualche altro valore (carattere).
Una situazione simile si applica a un oggetto istanziato di una classe. Considera il seguente programma:
#includereusando lo spazio dei nomi std;
classe Cla
pubblico:
char ch0 = 'un';
char ch1 = 'b';
char ch2 = 'c';
char ch3 = 'd';
;
intero principale()
const Cla obj;
restituisce 0;
A causa della dichiarazione “const Cla obj;” con const nella funzione main(), né 'a' né 'b' né 'c' né 'd' possono essere modificati in qualche altro valore.
Specificatori della classe di archiviazione:
Gli identificatori di classe di archiviazione sono statici, mutabili, thread_local ed extern.
Il Identificatore di classe di archiviazione statico
L'identificatore della classe di archiviazione statica consente alla variabile di vivere dopo che il suo ambito è stato completato, ma non è possibile accedervi direttamente.
Il seguente programma lo illustra, con una funzione ricorsiva:
#includereusando lo spazio dei nomi std;
funzione int()
statico int stac = 10;
cout << stac < 50)
cout << '\n';
restituisce 0;
funzione();
intero principale()
funzione();
restituisce 0;
L'uscita è:
10 20 30 40 50Se una variabile statica non viene inizializzata alla sua prima dichiarazione, assume il valore predefinito per il suo tipo.
L'identificatore statico può essere utilizzato anche con i membri di una classe; l'uso qui è diverso. Qui, consente l'accesso al membro senza istanziazione per l'oggetto.
Il seguente programma illustra questo per un membro dati:
#includereusando lo spazio dei nomi std;
classe Cla
pubblico:
statico const int num = 8;
;
intero principale()
cout << Cla::num << '\n';
restituisce 0;
L'uscita è:
8Il membro dei dati statici deve essere costante. Si noti che l'uso dell'operatore di risoluzione dell'ambito per accedere alla variabile statica al di fuori del suo ambito (nella funzione principale).
Il seguente programma illustra l'uso di "statico" per una funzione membro:
#includereusando lo spazio dei nomi std;
classe Cla
pubblico:
metodo del vuoto statico ()
cout << "Of static member function!" << '\n';
;
intero principale()
Cla::metodo();
restituisce 0;
L'uscita è:
Della funzione membro statica!
Si noti che l'uso dell'operatore di risoluzione dell'ambito per accedere alla funzione membro statico al di fuori del suo ambito (nella funzione principale).
Lo specificatore mutevole
Ricorda, da sopra, che se un oggetto istanziato inizia con const, il valore di nessuno dei suoi normali membri dati non può essere modificato. E affinché qualsiasi membro di tali dati possa essere modificato, deve essere dichiarato, mutabile.
Il seguente programma lo illustra:
#includereusando lo spazio dei nomi std;
classe Cla
pubblico:
char ch0 = 'un';
char ch1 = 'b';
carattere mutabile ch2 = 'c';
char ch3 = 'd';
;
intero principale()
const Cla obj;
obj.ch2 = 'z';
cout << obj.ch0 << " << obj.ch1 << " << obj.ch2 << " << obj.ch3 << " << '\n';
restituisce 0;
L'uscita è:
'a"b"z"d'Lo specificatore thread_local
Nella normale esecuzione di un programma, viene eseguito un segmento di codice, quindi il segmento di codice successivo, seguito da un altro segmento di codice e così via. Questo è un filo; il thread principale. Se due segmenti di codice vengono eseguiti contemporaneamente (stessa durata), è necessario un secondo thread. Il risultato del secondo thread potrebbe anche essere pronto prima del thread principale.
La funzione main() è come il thread principale. Un programma può avere più di due thread per un comportamento così asincrono.
Il secondo thread ha bisogno di uno scope (block scope) per funzionare. Questo è in genere fornito dall'ambito della funzione, una funzione. Una variabile in un ambito esterno che può essere visto nell'ambito del secondo thread.
Il seguente breve programma illustra l'uso dell'identificatore thread_local:
#includere#includere
usando lo spazio dei nomi std;
thread_local int inter = 1;
void thread_function()
inter = inter + 1;
cout << inter << "nd thread\n";
intero principale()
thread thr(&thread_function); // thr inizia a funzionare
cout << inter << "st or main thread\n";
attraverso.aderire(); // il thread principale aspetta che il thread finisca
restituisce 0;
L'uscita è:
1° o thread principale2° filo
La variabile, inter, preceduta da thread_local, significa che inter ha un'istanza separata in ogni thread. E che può essere modificato in thread diversi per avere valori diversi. In questo programma, viene assegnato il valore 1 nel thread principale e modificato al valore 2 nel secondo thread.
Un thread ha bisogno di un oggetto speciale per funzionare. Per questo programma, la libreria inclusa da “#include
La funzione membro join() per l'oggetto speciale, nella posizione utilizzata, fa in modo che il thread principale attenda che il secondo thread termini l'esecuzione prima di continuare l'esecuzione, altrimenti la funzione main() può uscire senza che il (secondo) thread abbia ha dato il suo risultato.
Lo specificatore esterno
In parole povere, per una dichiarazione non viene allocata memoria per la variabile o funzione, mentre per una definizione viene allocata memoria memory. La parola riservata extern consente di dichiarare una variabile o una funzione globale in un file ma definita in un altro. Tali file sono chiamati unità di traduzione per l'applicazione C++ completa.
Digita il seguente programma e salvalo con il nome del file, mainFile:
#includereusando lo spazio dei nomi std;
int mioInt;
const char ch;
void mioFn();
intero principale()
mioFn();
restituisce 0;
La variabile myInt, la variabile costante ch e la funzione myFn() sono state dichiarate senza essere definite.
Digita il seguente programma con le definizioni e salvalo con il nome del file, otherFile, nella stessa directory:
#includereusando lo spazio dei nomi std;
int mioInt = 10;
const char ch = 'c';
void myFn()
cout << "myFn() says " << myInt << " and " << ch <<'\n';
Prova a compilare l'applicazione dal terminale (prompt dei comandi DOS) con il seguente comando e nota che potrebbe non essere compilata:
g++ file principale.cpp altroFile.cpp -o completo.EXEOra, precedete le tre dichiarazioni in mainFile con la parola "extern", come segue:
extern int mioInt;extern const char ch;
extern void myFn();
Salva nuovamente il file principale. Compila l'applicazione con:
g++ file principale.cpp altroFile.cpp -o completo.EXE(Questo è il modo in cui vengono compilati file separati per la stessa applicazione in C++)
E dovrebbe compilare. Ora esegui l'applicazione, completa.exe e l'output dovrebbe essere:
myFn() dice 10 e cNota che con l'uso di "extern", una variabile costante può essere dichiarata in un file ma definita in un altro. Quando si ha a che fare con la dichiarazione e la definizione di funzioni in file diversi, l'uso di extern è facoltativo.
Quando usare extern? Usalo quando non hai file di intestazione con dichiarazioni globali.
"extern" viene utilizzato anche con le dichiarazioni dei modelli - vedere più avanti.
Conclusione:
Una variabile preceduta da const e/o volatile è un tipo qualificato cv. Una variabile, non preceduta da const o volatile o entrambi, è di tipo cv non qualificato.
Gli identificatori di classe di archiviazione sono statici, mutabili, thread_local ed extern. Questi influenzano la durata (durata), il luogo e il modo di impiego delle variabili in un'applicazione.