Vi los usos de estas dos frases: alcance global y espacio de nombres global. ¿Cuál es la diferencia entre ellos?Ámbito global vs espacio de nombres global
Respuesta
En C++, cada nombre tiene su alcance fuera de lo cual no existe. Un ámbito se puede definir de muchas maneras: puede ser definido por espacio de nombres , funciones, clases y simplemente {}.
Por lo tanto, un espacio de nombre, global o de otro tipo, define un ámbito. El espacio de nombres global se refiere al uso de ::
, y se dice que los símbolos definidos en este espacio de nombres tienen alcance global. Un símbolo, por defecto, existe en un espacio de nombres global, a menos que se define dentro de un bloque comienza con la palabra clave namespace
, o es un miembro de una clase, o una variable local de una función:
int a; //this a is defined in global namespace
//which means, its scope is global. It exists everywhere.
namespace N
{
int a; //it is defined in a non-global namespace called `N`
//outside N it doesn't exist.
}
void f()
{
int a; //its scope is the function itself.
//outside the function, a doesn't exist.
{
int a; //the curly braces defines this a's scope!
}
}
class A
{
int a; //its scope is the class itself.
//outside A, it doesn't exist.
};
También tenga en cuenta que un nombre se puede ocultar por el ámbito interno definido por espacio de nombres, función o clase. Por lo tanto, el nombre a
dentro del espacio de nombres N
oculta el nombre a
en el namspace global. De la misma manera, el nombre en la función y clase oculta el nombre en el espacio de nombres global. Si se enfrenta a esta situación, entonces se puede utilizar para referirse a ::a
el nombre definido en el espacio de nombres global:
int a = 10;
namespace N
{
int a = 100;
void f()
{
int a = 1000;
std::cout << a << std::endl; //prints 1000
std::cout << N::a << std::endl; //prints 100
std::cout << ::a << std::endl; //prints 10
}
}
Cuando se declara una variable global int i
por ejemplo, decimos i is in the global namespace
y has the global namespace scope
. Eso es todo.
Extracto de C++ 03:
3.3.5 Namespace scope
The outermost declarative region of a translation unit is also a namespace, called
the global namespace. A name declared in the global namespace has global namespace
scope (also called global scope).
"Ámbito" es un término más general que el "espacio de nombres". Cada bloque de espacio de nombres, clase y código define un ámbito en el que se pueden usar los nombres declarados en su interior; un espacio de nombres es un contenedor para nombres declarados fuera de clases y funciones.
"Ámbito global" y "espacio de nombre global" pueden usarse de manera más o menos intercambiable; el alcance de un nombre declarado en un espacio de nombres cubre la totalidad de ese espacio de nombres. Use "espacio de nombres" si se refiere específicamente al espacio de nombres, y "alcance" si se refiere a la visibilidad de los nombres que contiene.
El alcance denota la vida útil de un objeto, puede tener una variable global que existirá mientras el programa se ejecute, o puede tener una variable con un alcance de bloque que exista siempre que se ejecute ese bloque de código. Considere este ejemplo:
#include <iostream>
int a = 100;
main() {
int a = 200;
std::cout << "local a is: " << a << std::endl;
std::cout << "global a is: " << ::a << std::endl;
return 0;
}
Cuando ejecuta la instrucción imprimirá local a is: 200
, que se espera, obviamente, porque estamos redefiniendo a
en main
que deja en el ámbito de que está encerrando bloque. También imprimimos el ::a
global que nuevamente imprime el valor esperado 100, porque hemos solicitado el espacio de nombres global ::
.
Una semántica de espacio de nombres es en su mayoría lógica, es una forma de aislar simbiosis entre sí, con la esperanza de evitar conflictos de nombres, no afecta la vida útil de un objeto.
El alcance, por otro lado, denota la vida útil de un objeto, el a
global surgió antes que el a
local porque se construye mucho antes de que se ejecute main. Sin embargo, el alcance también fuerza un espacio de nombre en el símbolo, pero no de la misma manera que lo hace un namespace
. Hay diferentes tipos de ámbitos, global
, class
, function
, block
, file
etc ...
La parte confusa es que alcance a veces sobrecargado para indicar la visibilidad de un símbolo en particular, que es algo tomado de C, donde la noción de espacios de nombres no existía y el alcance se usaba para denotar tanto la vida útil como la visibilidad. En C++, sin embargo, las reglas cambiaron un poco, pero el término alcance se sigue utilizando de la misma manera porque los dos idiomas comparten una gran cantidad de conceptos.
Es bueno que haya resaltado la idea de que un alcance es inherente a la duración de un objeto. –
@Dmitriy Ryajov
El tema es un poco viejo pero quiero ofrecer mi ayuda en esto. Creo que no deberías hacer las cosas más complicadas de lo que realmente son. Scope
de un identificador es la parte de un programa de computadora donde el identificador, un nombre que se refiere a alguna entidad en el programa, se puede usar para encontrar la entidad referida. Entonces, el alcance del término solo se aplica a los identificadores y no deberíamos mezclarlo con la duración del objeto. Están un tanto conectados, pero no deberían mezclarse. La vida del objeto se denota por donde asignamos la memoria para ese objeto. Entonces, por ejemplo, si se asigna una memoria en la pila, se liberará tan pronto como la función termine. Entonces depende de dónde almacenamos el objeto y eso denota su duración. El alcance solo dice: "Aquí hay un nombre para un objeto y podemos usar este nombre para el objeto hasta ese momento". Entonces, como dije, el término scope
es solo para identificadores de los objetos y la duración es otra cosa que se denota por el lugar donde almacenamos el objeto.
Además, quiero decir algo sobre linkage
que está estrechamente relacionado con esto. Esto también puede ser a veces confuso. Digamos que tenemos algunos identificadores en el translation unit
que se refieren a algunos objetos. Si los mismos identificadores en la unidad de traducción other
se referirán a las mismas entidades se denota mediante el enlace. Entonces, por ejemplo, si un identificador tiene un enlace externo, podemos referirnos a la entidad a la que se refiere este identificador pero desde otra unidad de traducción al declararlo con la palabra clave extern
. Ahora, digamos que no queremos usar esa entidad en otras unidades de traducción. Entonces, la entidad va a exist
hasta que el programa termine pero cuando no lo declaramos, no podremos referirnos a él. También tenga en cuenta que ahora he mezclado los términos vinculación y duración. Pero esto se debe a que solo las entidades global
tienen enlaces externos. Un identificador dentro de una función no se puede referir a las otras partes del programa.
Conclusión: siempre trate de mantener las cosas simples. Me sorprendió cómo diferentes personas hablan sobre estos términos de manera diferente. Todo el proceso de compilación por separado es confuso, porque hay varios términos que tienen casi el mismo significado y probablemente todos se quedarán estancados en este punto.
- 1. variable global en espacio de nombres - valores difieren en hilos
- 2. ¿Qué significa que el espacio de nombres global estaría contaminado?
- 3. Global vs. Define
- 4. Estático vs global
- 5. Acceso al espacio de nombres global C++ desde otro espacio de nombre
- 6. ASP.NET MVC Session vs Global vs Cache
- 7. PHP: Los espacios de nombres en un único archivo con un espacio de nombres global
- 8. Cierres de PHP y ámbito de variable global implícita
- 9. PHP Namespace Global
- 10. Hacer script de PowerShell cmdlets ejecutar en el ámbito global
- 11. ASP.net MVC - variable global con ámbito de solicitud
- 12. node.js: Uso confuso de 'esto' en el ámbito global
- 13. El uso de global :: para espacios de nombres conflictivos
- 14. ¿Cómo puedo definir amigos en el espacio de nombres global dentro de otro espacio de nombres C++?
- 15. Cierre de JavaScript vs. variable global
- 16. objeto 'global' en Node.js
- 17. ¿Es posible crear un global sin ámbito en application.cfc?
- 18. Javascript Global Objects
- 19. ¿Por qué puedo llamar al constructor privado desde? Ámbito global?
- 20. MySql 'wait_timeout' Variable global vs Variable
- 21. Recurso global vs. Recurso local en ASP.NET
- 22. C++ singleton vs. objeto estático global
- 23. MySQL wait_timeout Variable - GLOBAL vs SESSION
- 24. Python: importación de clases de paquetes en el espacio de nombres global de la consola
- 25. Diferencia entre 'global' y 'estática global'
- 26. Método de clase global vs función vs clase estática
- 27. error C2039: 'memchr': no es miembro de '`espacio de nombres global' '
- 28. Cómo exponer los objetos javascript para pruebas de unidades sin contaminar el espacio de nombres global
- 29. ¿Cómo puedo rescindir/simular una función en el espacio de nombres global javascript
- 30. "use strict"; + jQuery.getScript() = el script no puede exportar al espacio de nombres global
¿Qué deberíamos hacer si queremos acceder a 'a' (definido en los espacios de nombre N) dentro de la función void f() {} – rimiro
@rimiro: Si 'a' se declara en un alcance de función, no puede acceder desde * fuera * de la función. – Nawaz