Condividi tramite


Ambito (C++)

Quando si dichiara un elemento di programma, ad esempio una classe, una funzione o una variabile, il relativo nome può essere "visto" e usato solo in determinate parti del programma. Il contesto in cui un nome è visibile è denominato ambito. Ad esempio, se si dichiara una variabile x all'interno di una funzione, x è visibile solo all'interno del corpo della funzione. Ha un ambito locale. Nel programma potrebbero essere presenti altre variabili con lo stesso nome; purché si trovino in ambiti diversi, non violano la regola di definizione unica e non viene generato alcun errore.

Per le variabili automatiche non statiche, l'ambito determina anche quando vengono creati e eliminati definitivamente nella memoria del programma.

Esistono sei tipi di ambito:

  • Ambito globale Un nome globale è uno dichiarato all'esterno di qualsiasi classe, funzione o spazio dei nomi. Tuttavia, in C++ anche questi nomi esistono con uno spazio dei nomi globale implicito. L'ambito dei nomi globali si estende dal punto di dichiarazione alla fine del file in cui vengono dichiarati. Per i nomi globali, la visibilità è disciplinata anche dalle regole di collegamento che determinano se il nome è visibile in altri file del programma.

  • Ambito dello spazio dei nomi Un nome dichiarato all'interno di uno spazio dei nomi, all'esterno di qualsiasi classe o definizione o blocco di funzioni, è visibile dal punto di dichiarazione alla fine dello spazio dei nomi. Uno spazio dei nomi può essere definito in più blocchi in file diversi.

  • Ambito locale Un nome dichiarato all'interno di una funzione o di un'espressione lambda, inclusi i nomi dei parametri, ha un ambito locale. Vengono spesso definiti "variabili locali". Sono visibili solo dal punto di dichiarazione alla fine della funzione o del corpo lambda. L'ambito locale è un tipo di ambito di blocco, illustrato più avanti in questo articolo.

  • I nomi dell'ambito della classe dei membri della classe hanno un ambito di classe, che si estende in tutta la definizione della classe indipendentemente dal punto di dichiarazione. L'accessibilità dei membri della classe è ulteriormente controllata dalle publicparole chiave , privatee protected . È possibile accedere ai membri pubblici o protetti solo usando gli operatori di selezione dei membri (. o ->) o operatori puntatore a membro (.* o ->*).

  • I nomi dell'ambito dell'istruzione dichiarati in un'istruzione for, ifwhile, , o switch sono visibili fino alla fine del blocco di istruzioni.

  • Ambito funzione Un'etichetta ha un ambito di funzione, il che significa che è visibile in tutto il corpo di una funzione anche prima del punto di dichiarazione. L'ambito della funzione consente di scrivere istruzioni come goto cleanup prima che l'etichetta cleanup venga dichiarata.

Nascondere nomi

È possibile nascondere un nome dichiarandolo in un blocco chiuso. Nella figura seguente i viene ridichiarato nel blocco interno, quindi nascondendo la variabile associata a i nell'ambito del blocco esterno.

Diagram that shows block scope name hiding.
Bloccare l'ambito e il nome nascosti

L'output del programma illustrato nella figura è:

i = 0
i = 7
j = 9
i = 0

Nota

L'argomento szWhat viene considerato nell'ambito della funzione. Di conseguenza, viene considerato come se fosse stato dichiarato nel blocco più esterno della funzione.

Nascondere nomi di classi

È possibile nascondere i nomi della classe mediante la dichiarazione di una funzione, un oggetto o una variabile o un enumeratore nello stesso ambito. Tuttavia, è comunque possibile accedere al nome della classe quando è preceduto dalla parola chiave class.

// hiding_class_names.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;

// Declare class Account at global scope.
class Account
{
public:
    Account( double InitialBalance )
        { balance = InitialBalance; }
    double GetBalance()
        { return balance; }
private:
    double balance;
};

double Account = 15.37;            // Hides class name Account

int main()
{
    class Account Checking( Account ); // Qualifies Account as
                                       //  class name

    cout << "Opening account with a balance of: "
         << Checking.GetBalance() << "\n";
}
//Output: Opening account with a balance of: 15.37

Nota

Qualsiasi posizione per cui viene chiamato il nome della classe (Account), la classe di parole chiave deve essere usata per distinguerla dalla variabile con ambito globale Account. Questa regola non viene applicata quando il nome della classe si trova a sinistra dell'operatore di risoluzione dell'ambito (::). I nomi a sinistra dell'operatore di risoluzione dell'ambito vengono sempre considerati nomi classe.

Nell'esempio seguente viene illustrato come dichiarare un puntatore a un oggetto di tipo Account usando la class parola chiave :

class Account *Checking = new class Account( Account );

L'oggetto Account nell'inizializzatore (tra parentesi) nell'istruzione precedente ha un ambito globale; è di tipo double.

Nota

Il riutilizzo dei nomi degli identificatori come illustrato in questo esempio viene considerato uno stile di programmazione di qualità insufficiente.

Per informazioni sulla dichiarazione e l'inizializzazione di oggetti classe, vedere Classi, strutture e unioni. Per informazioni sull'uso degli new operatori di archivio gratuito e delete , vedere operatori nuovi ed eliminati.

Nascondere i nomi con ambito globale

È possibile nascondere i nomi con ambito globale dichiarando in modo esplicito lo stesso nome nell'ambito del blocco. È tuttavia possibile accedere ai nomi di ambito globale usando l'operatore di risoluzione dell'ambito (::).

#include <iostream>

int i = 7;   // i has global scope, outside all blocks
using namespace std;

int main( int argc, char *argv[] ) {
   int i = 5;   // i has block scope, hides i at global scope
   cout << "Block-scoped i has the value: " << i << "\n";
   cout << "Global-scoped i has the value: " << ::i << "\n";
}
Block-scoped i has the value: 5
Global-scoped i has the value: 7

Vedi anche

Concetti di base