Ámbito (C++)

Cuando se declara un elemento de programa como una clase, función o variable, su nombre solo se puede "ver" y usar en determinadas partes del programa. El contexto en el que se ve un nombre se denomina ámbito. Por ejemplo, si declara una variable x dentro de una función, x solo es visible dentro de ese cuerpo de la función. Tiene ámbito local. Es posible que tenga otras variables con el mismo nombre en el programa; siempre que estén en distintos ámbitos, no infringen la regla de definición única y no se genera ningún error.

Para las variables no estáticas automáticas, el ámbito también determina cuándo se crean y destruyen en la memoria del programa.

Hay seis tipos de ámbito:

  • Ámbito global Un nombre global es uno que se declara fuera de cualquier clase, función o espacio de nombres. Sin embargo, en C++ incluso estos nombres existen con un espacio de nombres global implícito. El ámbito de los nombres globales se extiende desde el punto de declaración hasta el final del archivo en el que se declaran. En el caso de los nombres globales, la visibilidad también se rige por las reglas de vinculación que determinan si el nombre es visible en otros archivos del programa.

  • Ámbito del espacio de nombres Un nombre que se declara dentro de un espacio de nombres, fuera de cualquier clase o definición de enumeración o bloque de función, es visible desde su punto de declaración hasta el final del espacio de nombres. Un espacio de nombres se puede definir en varios bloques en distintos archivos.

  • Ámbito local Un nombre declarado dentro de una función o lambda, incluidos los nombres de parámetro, tienen ámbito local. A menudo se conocen como "locales". Solo son visibles desde su punto de declaración hasta el final de la función o cuerpo lambda. El ámbito local es un tipo de ámbito de bloque, que se describe más adelante en este artículo.

  • Ámbito de clase Los nombres de los miembros de clase tienen ámbito de clase, que se extiende a lo largo de la definición de clase independientemente del punto de declaración. La accesibilidad de los miembros de clase se controla aún más mediante las palabras clave public, privatey protected. Solo se puede acceder a los miembros públicos o protegidos mediante los operadores de selección de miembros (. o ->) o operadores de puntero a miembro (.* o ->*).

  • Ámbito de instrucción Los nombres declarados en una instrucción for, if, while o switch son visibles hasta el final del bloque de instrucciones.

  • Ámbito de función Una etiqueta tiene ámbito de función, lo que significa que es visible a lo largo de un cuerpo de función incluso antes de su punto de declaración. El ámbito de función permite escribir instrucciones como goto cleanup antes de declarar la etiqueta cleanup.

Ocultar nombres

Puede ocultar un nombre declarándolo en un bloque delimitado. En la ilustración siguiente, i se declara dentro del bloque interno, ocultando de esta manera la variable asociada a i en el ámbito del bloque externo.

Diagram that shows block scope name hiding.
Ámbito de bloque y ocultación de nombres

El resultado del programa que se muestra en la figura es:

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

Nota:

El argumento szWhat se considera en el ámbito de la función. Por consiguiente, se trata como si se hubiera declarado en el bloque exterior de la función.

Ocultar nombres de clase

Puede ocultar nombres de clase declarando una función, un objeto o una variable, o un enumerador en el mismo ámbito. Sin embargo, aún se puede tener acceso al nombre de clase cuando va precedido por la palabra clave 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:

En cualquier lugar donde se llame al nombre de clase (Account), se debe usar la palabra clave class para diferenciarla de la variable Account del ámbito global. Esta regla no se aplica cuando el nombre de clase aparece a la izquierda del operador de resolución de ámbito (::). Los nombres del lado izquierdo del operador de resolución de ámbito siempre se consideran nombres de clase.

En el ejemplo siguiente se muestra cómo declarar un puntero a un objeto de tipo Account mediante la palabra clave class:

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

Account en el inicializador (entre paréntesis) de la instrucción anterior tiene ámbito de archivo; es de tipo double.

Nota:

La reutilización de los nombres de identificador, tal y como se muestra en este ejemplo, se considera mal estilo de programación.

Para obtener información sobre la declaración y la inicialización de los objetos de clase, vea Clases, estructuras y uniones. Para obtener información sobre cómo utilizar los operadores de almacenamiento libre new y delete, vea Operadores new y delete.

Ocultar nombres con ámbito global

Puede ocultar nombres con ámbito global declarando explícitamente el mismo nombre en ámbito de bloque. Sin embargo, se puede obtener acceso a los nombres de ámbito global usando el operador de resolución de ámbito (::).

#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

Consulte también

Conceptos básicos