Alcance en C ++

Alcance en C ++

Una entidad en C ++ tiene un nombre, que puede ser declarada y/o definida. Una declaración es una definición, pero una definición no es necesariamente una declaración. Una definición asigna memoria para la entidad nombrada, pero una declaración puede o no asignar memoria para la entidad nombrada. Una región declarativa es la parte más grande de un programa en el que el nombre de una entidad (variable) es válido. Esa región se llama alcance o alcance potencial. Este artículo explica el alcance en C++. Además, se requiere un conocimiento básico de C ++ para comprender este artículo.

Contenido del artículo

  • Región declarativa y alcance
  • Alcance global
  • Variables globales y alcance global
  • Alcance
  • Alcance de la función
  • Alcance de la clase
  • Alcance de la enumeración
  • Variable global
  • Alcance del parámetro de plantilla
  • Nombre Ocultación
  • Posibilidad de repetir la declaración en el mismo alcance
  • Alcance del espacio de nombres
  • Alcance en diferentes porciones
  • Conclusión

Región declarativa y alcance

Una región declarativa es la parte más grande de un texto del programa en el que el nombre de una entidad es válido. La región donde se puede usar el nombre no calificado (visto) para referirse a la misma entidad. Considere el siguiente programa corto:

#incluir
usando el espacio de nombres STD;
nulo fn ()

int var = 3;
if (1 == 1)

cout<

int main ()

fn ();
regresar 0;

La función fn () tiene dos bloques: un bloque interno para la condición if y un bloque exterior para el cuerpo de la función. El identificador, var, se introduce y se ve en el bloque exterior. También se ve en el bloque interno, con la declaración de cout. Los bloques externos e internos son el alcance del nombre, var.

Sin embargo, el nombre, var, aún se puede usar para declarar una entidad diferente, como un flotador, en el bloque interno. El siguiente código ilustra esto:

#incluir
usando el espacio de nombres STD;
nulo fn ()

int var = 3;
if (1 == 1)

flotante var = 7.5;
cout<

int main ()

fn ();
regresar 0;

La salida es

7.5

En este caso, el nombre, var, ya no se puede usar en el bloque interno para referirse al entero del valor 3, que se introdujo (declarado) en el bloque exterior. Dichos bloques internos se denominan alcance potencial para las entidades declaradas en el bloque exterior.

Nota: una entidad del mismo tipo, como el bloque exterior, aún se puede declarar en el bloque interno. Sin embargo, en este caso, la nueva declaración y su significado son válidos en el bloque interno, mientras que la antigua declaración y el significado fuera del bloque interno siguen siendo válidos solo en el bloque exterior.

Una declaración del mismo nombre en un bloque interno normalmente anula la declaración del mismo nombre fuera de ese bloque interno. Los bloques internos pueden anidar otros bloques internos.

Alcance global

Cuando un programador comienza a escribir un archivo, ese es el alcance global. El siguiente programa corto ilustra esto:

#incluir
usando el espacio de nombres STD;
flotante var = 9.4;
int main ()

cout <cout <<::var<<'\n';
regresar 0;

La salida es:

9.4
9.4

En este caso, la región declarativa o el alcance de VAR comienza desde el punto de declaración para VAR, y continúa hacia abajo hasta el final del archivo (unidad de traducción).

El bloque de la función Main () es un alcance diferente; Es un alcance anidado para el alcance global. Para acceder a una entidad del alcance global desde un alcance diferente, el identificador es utilizado directamente o precedido por el operador de resolución de alcance, :: .

Nota: La entidad, Main (), también se declara en el alcance global.

Alcance

Las declaraciones if, mientras, para o para el cambio o el cambio pueden definir cada uno un bloque. Tal declaración es una declaración compuesta. El nombre de una variable declarada en un bloque tiene un alcance de un bloque. Su alcance comienza a su punto de declaración y termina al final de su bloqueo. El siguiente programa corto ilustra esto para la variable, identificación:

#incluir
usando el espacio de nombres STD;
int main ()

if (1 == 1)

/*Algunas declaraciones*/
int ident = 5;
cout</*Algunas declaraciones*/

regresar 0;

Una variable, como Ident, declarada en el alcance del bloque es una variable local.

Una variable declarada fuera del alcance del bloque y arriba se puede ver en el encabezado del bloque (E.gramo., condición para if bloque) y dentro del bloque. El siguiente programa corto ilustra esto para la variable, Identif:

#incluir
usando el espacio de nombres STD;
int main ()

int identif = 8;
if (identif == 8)

cout<
regresar 0;

La salida es,

8

Hay dos ámbitos de bloque: el bloque para la función main () y la declaración de compuesto IF anidada. El bloque anidado es el alcance potencial del bloque de función principal ().

No se puede ver una declaración introducida en un alcance de bloque fuera del bloque. El siguiente programa corto, que no se compila, lo ilustra con la variable, variAb:

#incluir
usando el espacio de nombres STD;
int main ()

if (1 == 1)

int variab = 15;

cout<regresar 0;

El compilador produce un mensaje de error para variAb.

Una entidad introducida, declarada en el encabezado de una función compuesta, no se puede ver afuera (a continuación) la declaración compuesta. El siguiente código for-loop no se compilará, lo que resulta en un mensaje de error:

#incluir
usando el espacio de nombres STD;
int main ()

para (int i = 0; i<4; ++i)

cout<
cout<regresar 0;

La variable de iteración, i se ve dentro del bloque de bucle para el bucle, pero no fuera del bloqueo de bucle.

Alcance de la función

Se ve un parámetro de función en el bloque de funciones. Una entidad declarada en un bloque de funciones se ve desde el punto de declaración hasta el final del bloque de funciones. El siguiente programa corto ilustra esto:

#incluir
#incluir
usando el espacio de nombres STD;
cadena fn (string str)

char stri [] = "plátanos";
/*Otras declaraciones*/
cadena TotalStr = Str + Stri;
regresar TotalStr;

int main ()

cadena totstr = fn ("comer");
cout<regresar 0;

La salida es:

Comer plátanos

Nota: Se puede ver una entidad declarada fuera de la función (arriba) en la lista de parámetros de la función y el bloque de funciones.

Etiqueta

El alcance de una etiqueta es la función en la que aparece. El siguiente código ilustra esto:

#incluir
usando el espacio de nombres STD;
nulo fn ()

goto labl;
/*Otras declaraciones*/
labl: int Inte = 2;
cout<
int main ()

fn ();
regresar 0;

La salida es

2

Alcance de la clase

Con el alcance normal, la región declarativa comienza desde un punto del programa, continúa y se detiene en un punto diferente. El alcance existe en una región continua. Con la clase, el alcance de una entidad puede estar en diferentes regiones que no están unidas. Todavía se aplican las reglas de los bloques anidados. El siguiente programa ilustra esto:

#incluir
usando el espacio de nombres STD;
// clase base
Clase CLA

privado:
int memp = 5;
protegido:
int memPro = 9;
público:
nulo fn ()

cout<
;
//Clase derivada
Clase Dercla: CLA público

público:
int dermem = memPro;
;
int main ()

Cla obj;
obj.fn ();
Dercla DeRobj;
cout<regresar 0;

La salida es:

5
9

En la clase CLA, la MEMP variable, se ve en el punto de declaración. Después de eso, la parte corta de "protegida" se omite y se ve nuevamente en el bloque de funciones de miembro de la clase. La clase derivada se omite y se ve nuevamente en el alcance de la función principal () (bloque).

En la clase CLA, la variable, mempro, se ve en el punto de declaración. La parte de la función pública fn () se omite y luego se ve en el bloque de descripción de la clase derivada. Se ve de nuevo en la función principal ().

Operador de resolución de alcance

El operador de resolución de alcance en C ++ es :: . Se utiliza para acceder a un miembro estático de la clase. El siguiente programa ilustra esto:

#incluir
usando el espacio de nombres STD;
Clase CLA

público:
static int const mem = 5;
público:
void estático fn ()

cout<
;
int main ()

cout<Cla :: fn ();
regresar 0;

La salida es:

5
5

Los miembros estáticos se ven en el bloque de funciones Main (), a los que se accede utilizando el operador de resolución de alcance.

Alcance de la enumeración

Enumeración sin cicatrices

Considere lo siguiente if Block:

if (1 == 1)

enum a, b, c = b+2;
cout<

La salida es:

0 1 3

La primera línea en el bloque es una enumeración; A, B y C son sus enumeradores. El alcance de un enumerador comienza desde el punto de su declaración, hasta el final del bloque de la enumeración.

La siguiente declaración no se compilará porque el punto de declaración de C es después del de A:

enum a = c+2, b, c;

El siguiente segmento de código no se compilará porque se accede a los enumeradores después del bloque adjunto de la enumeración:

if (1 == 1)

enum a, b, c = b+2;

cout<

La enumeración previa se describe como una enumeración sin cable, y sus enumeradores se definen como enumeradores sin cable. Esto se debe a que comienza solo con la palabra reservada, enum. Las enumeraciones que comienzan con la clase enum o la estructura de enum. Sus enumeradores se definen como enumeradores de alcance.

Enumeración de alcance

La siguiente declaración está bien:

Enum class nam a, b, c = b+2;

Este es un ejemplo de una enumeración alcanzada. El nombre de la clase es nam. Aquí, el alcance del enumerador comienza desde el punto de declaración hasta el final de la definición de enumeración y no del final del bloque de encierra para la enumeración. El siguiente código no compilará:

if (1 == 1)

Enum class nam a, b, c = b+2;
cout<

Uso simple de enumeración alcanzada

El siguiente código muestra una forma simple de usar enumeración con alcance:

if (1 == 1)

enum nam a, b, c = b+2;
cout << c << endl; //simple usage

La salida es 3, ya que B es 1 ('A' es 0).

Variable global

Una variable global es una variable declarada en el alcance global. Cuando un programador comienza a escribir un archivo, ese es el alcance global. Considere el siguiente programa:

#incluir
usando el espacio de nombres STD;
char va = 'a';
int main ()

cout <cout <<::va<<'\n';
regresar 0;

La salida es:

A
A

En este programa, la parte o el alcance de VA comienza desde el punto de declaración de VA y continúa hacia abajo hasta el final de la unidad de traducción (archivo).

El cuerpo de la función Main () es un alcance diferente por derecho propio; El alcance global anida el alcance de la función principal ().

La variable VA es una variable de alcance global o una variable simplemente global porque se puede ver en todas partes del archivo, comenzando desde donde se ha declarado. Se puede ver en el alcance de la función principal ().

Para acceder a una variable global (variable del alcance global) desde un alcance diferente, el nombre de la variable se usa directamente o precede por el operador de resolución de alcance, :: como se muestra en el programa anterior.

La declaración if, mientras, para o de cambio, puede definir cada uno un bloque. Tal declaración es una declaración compuesta. El nombre de una variable declarada en un bloque tiene un alcance de un bloque. Su alcance comienza a su punto de declaración y termina al final de su bloqueo. El siguiente programa corto ilustra esto para la variable, identificación:

#incluir
usando el espacio de nombres STD;
int main ()

if (1 == 1)

/*Algunas declaraciones*/
int ident = 5;
cout</*Algunas declaraciones*/

regresar 0;

Una variable, como Ident, declarada en el alcance del bloque es una variable local.

Una variable declarada fuera del alcance del bloque y arriba se puede ver en el encabezado del bloque (E.gramo., condición para if bloque) y dentro del bloque. El siguiente programa corto ilustra esto para la variable, Identif:

#incluir
usando el espacio de nombres STD;
int main ()

int identif = 8;
if (identif == 8)

cout<
regresar 0;

La salida es,

8

Aquí hay dos ámbitos de bloque: el bloque para la función main () y la declaración de compuesto IF anidada. El bloque anidado es el alcance potencial del bloque de función principal ().

No se puede ver una declaración introducida en un alcance de bloque fuera del bloque. El siguiente programa corto, que no se compila, lo ilustra con la variable, variAb:

#incluir
usando el espacio de nombres STD;
int main ()

if (1 == 1)

int variab = 15;

cout<regresar 0;

El compilador produce un mensaje de error para variAb.

Una entidad introducida, declarada en el encabezado de una función compuesta, no se puede ver afuera (a continuación) la declaración compuesta. El siguiente código for-loop no se compilará, lo que resulta en un mensaje de error:

#incluir
usando el espacio de nombres STD;
int main ()

para (int i = 0; i<4; ++i)

cout<
cout<regresar 0;

La variable de iteración, i se ve dentro del bloque de bucle para el bucle, pero no fuera del bloqueo de bucle.

Una variable declarada en el alcance global es una variable global. Se puede ver dentro de un alcance de bloque. El siguiente programa ilustra esto:

#incluir
usando el espacio de nombres STD;
int glb = 5;
int main ()

cout << glb << endl;
regresar 0;

La salida es 5.

Reasignación no permitida en el alcance global

En el programa anterior, la declaración:

int glb = 5;

Es una declaración con inicialización (primera asignación de valor) simultáneamente. En el siguiente programa, la declaración "int glb; tiene cero asignado por defecto. La línea posterior (glb = 5;) intenta reasignación del valor, 5, en el alcance global. Esto crea un error, y el programa no compila. El programa es:

#incluir
usando el espacio de nombres STD;
int glb;
glb = 5;
int main ()

cout << glb << endl;
regresar 0;

Sin embargo, la reasignación tendrá lugar en un alcance local (bloque), como se muestra en el siguiente programa:

#incluir
usando el espacio de nombres STD;
int glb;
int main ()

if (1 == 1)
glb = 5;
cout << glb << endl;

regresar 0;

La salida es 5.

Puntero global

Cuando se declara un puntero en el alcance global, se puede ver en un alcance anidado. No se puede ver un puntero declarado en un alcance anidado fuera del alcance anidado. Hay dos formas de declarar un puntero. Se puede declarar un puntero con una tarea práctica (de una dirección). Se puede declarar un puntero sin una tarea práctica. Si el puntero se declara sin una asignación práctica en el alcance global, entonces no se puede reasignar en el alcance global. Sin embargo, en este caso, se puede reasignar en un alcance anidado.

Matriz global

Cuando se declara una matriz en el alcance global, se puede ver en un alcance anidado. Una matriz declarada en un alcance anidado, no se puede ver fuera del alcance anidado. Hay dos formas de declarar una matriz. Se puede declarar una matriz con una tarea práctica (de una dirección). Se puede declarar una matriz sin una tarea práctica. Si la matriz se declara sin asignación práctica en el alcance global, entonces no se puede reasignar en el alcance global. Sin embargo, se puede reasignar en un alcance anidado (elemento por elemento).

Alcance del parámetro de plantilla

El alcance normal de un nombre de parámetro de plantilla comienza desde el punto de declaración hasta el final de su bloque, como en el siguiente ejemplo:

plantilla estructura de edades

T John = 11;
U Peter = 12.3;
T Mary = 13;
U Joy = 14.6;
;

U y t se ven dentro del bloque.

Para un prototipo de función de plantilla, el alcance comienza desde el punto de declaración hasta el final de la lista de parámetros de función, como en la siguiente declaración:

plantilla nulo func (t no, u cha, const char *str);

Sin embargo, cuando se trata de la descripción de la clase (definición), el alcance también puede ser de diferentes porciones, como en el siguiente programa de ejemplo:

#incluir
usando el espacio de nombres STD;
plantilla Clase THECLA

público:
T num;
estático u ch;
nulo func (u cha, const char *str)

cout << "There are " << num << " books worth " << cha << str << " in the store." << '\n';

diversión nula estática (u ch)

if (ch == 'a')
cout << "Official static member function" << '\n';

;
int main ()

THECLA obj;
obj.num = 12;
obj.func ('$', "500");
regresar 0;

Nombre Ocultación

Un ejemplo de ocultación de nombre ocurre cuando el nombre del mismo tipo de objeto se vuelve a decidir en un bloque anidado. El siguiente programa ilustra esto:

#incluir
usando el espacio de nombres STD;
nulo fn ()

int var = 3;
if (1 == 1)

int var = 4;
cout<
cout<
int main ()

fn ();
regresar 0;

La salida es:

4
3

Es porque var en el bloque anidado oculta var en el bloque exterior.

Posibilidad de repetir la declaración en el mismo alcance

El punto de la declaración es donde se introduce el nombre (por primera vez) en su alcance.

Prototipo de funciones

Diferentes entidades, incluso de diferentes tipos, normalmente no pueden declararse en el mismo alcance. Sin embargo, un prototipo de función puede declararse más de una vez en el mismo alcance. El siguiente programa con dos prototipos de funciones y la definición de función correspondiente ilustra esto:

#incluir
usando el espacio de nombres STD;
void fn (int num);
void fn (int num);
nulo fn (int num)

cout<
int main ()

fn (5);
regresar 0;

El programa funciona.

Funciones sobrecargadas

Las funciones sobrecargadas son funciones con el mismo nombre pero con diferentes firmas de funciones. Como otra excepción, las funciones sobrecargadas con el mismo nombre se pueden definir en el mismo alcance. El siguiente programa ilustra esto:

#incluir
usando el espacio de nombres STD;
nulo fn (int num)

cout<
Vacío FN (Float no)

cout<
int main ()

fn (5);
flotante flt = 8.7;
fn (FLT);
regresar 0;

La salida es:

5
8.7

Las funciones sobrecargadas se han definido en el alcance global.

Alcance del espacio de nombres

Dado que dos variables diferentes pueden tener el mismo nombre y para diferenciarlas, las variables deben declararse en dos espacios de nombres diferentes. Un espacio de nombres es un bloque con un nombre, que tiene sus propias entidades nombradas. El nombre de un espacio de nombres es el nombre del bloque. Dos espacios de nombres diferentes pueden tener entidades con los mismos nombres. El siguiente programa ilustra esto:

#incluir
usando el espacio de nombres STD;
espacio de nombres na

char ch1;
char ch2 = 'Q';

espacio de nombres nb

char ch1;
char ch2 = 'y';

int main ()

Na :: ch1 = 'p';
cout << NA::ch1 << endl;
Nb :: ch1 = 'x';
cout << NB::ch1 << endl;
regresar 0;

La salida es:

PAG
X

Hay dos espacios de nombres: NA y NB. El espacio predefinido para NA es su bloqueo. El espacio predefinido para NB también es su bloqueo. Tenga en cuenta que las entidades en los dos bloques diferentes tienen los mismos nombres. Para declarar un espacio de nombres, comience con la palabra reservada, espacio de nombres; Sigue un espacio, luego el bloque con sus entidades.

Para acceder a una entidad fuera del bloque del espacio de nombres, comience con el nombre del espacio de nombres. Esto es seguido por el operador de resolución de alcance y luego el nombre de la entidad.

El alcance de la variable, Na :: CH1, comienza desde el punto de declaración de CH1 en el bloque NA. Termina al final del bloque de NA y luego aparece en cualquier línea afuera (y debajo) del bloque, donde se usa "Na ::". El alcance de la variable, NB :: CH1, comienza desde el punto de declaración de CH1 en el bloque NB. Termina al final del bloque NB y aparece en cualquier línea afuera (y debajo) del bloque, donde se usa "NB ::".

Un alcance del espacio de nombres se refiere a una entidad declarada en el bloque de nombres. El alcance de la entidad del espacio de nombres es el bloque de espacio de nombres y cualquier línea fuera del bloque que use el nombre del espacio de nombres.

Alcance en diferentes porciones

La clase anterior y los ámbitos del espacio de nombres han ilustrado cómo un alcance puede estar en diferentes partes del texto del programa. Otro buen ejemplo es el especificador de amigo.

Amigo especificador

Si la Clase C se declara como un amigo de la Clase A, en la definición de Clase A, entonces todas las funciones de miembros públicos de la Clase C pueden acceder a los miembros de datos privados (y las funciones de los miembros privados) de la Clase A. El siguiente programa ilustra esto:

#incluir
usando el espacio de nombres STD;
clase A
Privado: int d = 5;
Amigo Clase C;
;
clase B
/*
public: int fb ()
A a;
devolver un.d;

*/
;
clase C
public: int fc ()
A a;
devolver un.d;

;
int main ()

A a;
B b;
C c;
// int ret1 = b.pensión completa();
int ret2 = c.fc ();
cout << ret2 << endl;
regresar 0;

La salida es 5. En la definición de Clase A, la Clase C se declara como un amigo de la Clase A. Entonces, fc () de la definición de clase C, puede ver D de la definición de clase A. El programa compila. Si se eliminan los símbolos de comentarios, entonces el programa no se compilará porque la clase B no ha sido declarada amiga en la clase A.

El alcance de la variable privada B comienza desde su punto de declaración y termina al final del bloque Clase A. También aparece en la función fc () en la clase C, que es un amigo de la clase A. Las dos porciones para el alcance son el bloque de clase A y el bloque de función Fc ().

Conclusión

Un alcance es una región declarativa. Una región declarativa es la parte más grande de un texto del programa en el que el nombre de una entidad es válido. Se puede dividir en más de una porción con ciertos esquemas de programación, como bloques anidados. Las porciones que no tienen el punto de declaración forman el alcance potencial. El alcance potencial puede o no tener la declaración.