English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Manuale di base di C++

Controllo dei flussi C++

Funzioni in C++

Array & stringhe C++

Strutture dati C++

Classi & oggetti C++

Puntatore in C++

Ereditarietà in C++

Tutorial STL di C++

Manuale di riferimento C++

Classe di archiviazione in C++

Ogni variabile in C++ ha due caratteristiche: tipo e classe di memoria.

La specifica del tipo indica il tipo di dati che può essere memorizzato nella variabile. Ad esempio: int, float, char ecc.

Inoltre, le classi di memoria controllano due attributi diversi delle variabili: la vita utile (determina per quanto tempo la variabile può esistere) e l'ambito (determina quale parte del programma può accedervi).

La definizione di classe di memoria definisce l'intervallo (visibilità) e la vita utile delle variabili/funzioni nel programma C++. Questi segnalatori vengono posizionati prima del tipo che li modificano. Di seguito è riportato un elenco delle classi di memoria disponibili nel programma C++:

  • auto

  • register

  • static

  • extern

  • mutable

  • thread_local (C++11)

Da C++ 17 in poi, la parola chiave auto non è più un'indicazione di classe di memoria in C++ e la parola chiave register è stata abbandonata.

Classe di memoria auto

Da C++ 11 in poi,auto La parola chiave viene utilizzata in due casi: per inferire automaticamente il tipo della variabile in base all'espressione di inizializzazione durante la dichiarazione delle variabili e come segnaposto per il valore di ritorno della funzione durante la dichiarazione della funzione.

La parola chiave auto nello standard C++98 viene utilizzata per la dichiarazione di variabili automatiche, ma è stata eliminata in C++11 a causa dell'uso estremamente raro e inutile.

L'inferenza del tipo della variabile viene effettuata automaticamente in base all'espressione di inizializzazione, come:

auto f=3.14; // double
auto s("hello"); // const char*
auto z = new auto(9); // int*
auto x1 = 5, x2 = 5.0, x3='r';// errore, deve essere inizializzato con lo stesso tipo

Classe di memoria register

register La classe di memoria viene utilizzata per definire le variabili locali memorizzate nel registro invece della RAM. Questo significa che la dimensione massima della variabile è uguale alla dimensione del registro (solitamente una parola) e non può essere applicato l'operatore unario '&' (poiché non ha un indirizzo di memoria).

{
   register int miles;
{}

Il registro viene utilizzato solo per le variabili che richiedono un accesso veloce, come i contatori. Si dovrebbe anche notare che la definizione di 'register' non significa che la variabile verrà memorizzata nel registro, ma che potrebbe essere memorizzata nel registro, a seconda dei limiti hardware e dell'implementazione.

Classe di memoria statica

static L'indicatore di memoria statica richiede al compilatore di mantenere l'esistenza dei variabili locali nel ciclo di vita del programma, senza doverli creare e distruggere ogni volta che entrano e escono dalla sfera di azione. Pertanto, l'uso del modificatore static per le variabili locali può mantenere il valore delle variabili tra le chiamate di funzione.

Il modificatore 'static' può anche essere applicato a variabili globali. Quando 'static' viene applicato a una variabile globale, limita l'ambito della variabile al file in cui è stata dichiarata.

In C++, quando 'static' viene usato come membro dati statico di una classe, provoca che solo una copia di tale membro venga condivisa tra tutti gli oggetti della classe.

#include <iostream>
 
// dichiarazione della funzione 
void func(void);
 
static int count = 25; /* variabile globale */
 
int main()
{
    while(count--)
    {
       func();
    {}
    return 0;
{}
// definizione della funzione
void func(void)
{
    static int i = 8; // variabile statica locale
    i++;
    std::cout << "variabile 'i' è " << i;
    std::cout << ", variabile 'count' è " << count << std::endl;
{}

Quando il codice sopra viene compilato ed eseguito, produrrà i seguenti risultati:

La variabile 'i' è 9, la variabile 'count' è 24
La variabile 'i' è 10, la variabile 'count' è 23
La variabile 'i' è 11, la variabile 'count' è 22
La variabile 'i' è 12, la variabile 'count' è 21
La variabile 'i' è 13, la variabile 'count' è 20
La variabile 'i' è 14, la variabile 'count' è 19
La variabile 'i' è 15, la variabile 'count' è 18
La variabile 'i' è 16, la variabile 'count' è 17
La variabile 'i' è 17, la variabile 'count' è 16
La variabile 'i' è 18, la variabile 'count' è 15
La variabile 'i' è 19, la variabile 'count' è 14
La variabile 'i' è 20, la variabile 'count' è 13
La variabile 'i' è 21, la variabile 'count' è 12
La variabile 'i' è 22, la variabile 'count' è 11
La variabile 'i' è 23, la variabile 'count' è 10
La variabile 'i' è 24, la variabile 'count' è 9
La variabile 'i' è 25, la variabile 'count' è 8
La variabile 'i' è 26, la variabile 'count' è 7
La variabile 'i' è 27, la variabile 'count' è 6
La variabile 'i' è 28, la variabile 'count' è 5
La variabile 'i' è 29, la variabile 'count' è 4
La variabile 'i' è 30, la variabile 'count' è 3
La variabile 'i' è 31, la variabile 'count' è 2
La variabile i è 32, la variabile count è 1
La variabile i è 33, la variabile count è 0

Classe di memoria extern

extern La classe di memoria fornisce un riferimento alla variabile globale, che è visibile a tutti i file del programma. Quando si utilizza 'extern', per le variabili che non possono essere inizializzate, il nome della variabile puntano a una posizione di memoria precedentemente definita.

Quando hai più file e hai definito una variabile o funzione che può essere utilizzata in altri file, puoi usarla in altri file extern per ottenere un riferimento alla variabile o funzione già definita. Puoi intenderlo così:extern è utilizzato per dichiarare una variabile globale o funzione in un altro file.

Il modificatore extern viene utilizzato di solito quando ci sono due o più file che condividono la stessa variabile globale o funzione, come segue:

Primo file: main.cpp

#include <iostream>
 
int count;
extern void write_extern();
 
int main()
{
   count = 5;
   write_extern();
{}

Secondo file: support.cpp

#include <iostream>
 
extern int count;
 
void write_extern(void)
{
   std::cout << "Count è " << count << std::endl;
{}

In questo caso, il secondo file contiene extern La parola chiave viene utilizzata per dichiarare un count già definito nel primo file main.cpp. Ora, compilare questi due file come segue:

$ g++ main.cpp support.cpp -o write

Questo produrrà write Eseguibile, tentativo di esecuzione writeQuesto produrrà i seguenti risultati:

$ ./write
Count è 5

mutable classe di memoria

mutable Il modificatore è applicabile solo agli oggetti della classe, che verrà spiegato alla fine di questo tutorial. Permette che i membri dell'oggetto sostituiscano i costanti. Ciò significa che i membri mutable possono essere modificati tramite funzioni membri const.

thread_local classe di memoria

Le variabili dichiarate con il modificatore thread_local sono accessibili solo sulla thread su cui sono state create. Le variabili vengono create quando viene creato il thread e distrutte quando il thread viene distrutto. Ogni thread ha la sua propria copia delle variabili.

Il modificatore thread_local può essere combinato con static o extern.

thread_local può essere applicato solo alla dichiarazione e definizione dei dati, thread_local non può essere utilizzato nella dichiarazione o definizione di funzione.

Di seguito è riportato un esempio di variabili che possono essere dichiarate come thread_local:

thread_local int x; // Variabile globale nel namespace
class X
{
    static thread_local std::string s; // Variabile membro statica della classe
};
static thread_local std::string X::s; // X::s deve essere definito
 
void foo()
{
    thread_local std::vector<int> v; // Variabile locale
{}