C++ - espacio de nombres

Tabla de contenido

1. Conflicto de nombres en lenguaje C

2. Definición del espacio de nombres

3. Uso del espacio de nombres

  • Quizás cuando mires el código C++ escrito por otros, incluyas este archivo de encabezado al principio: #include<iostream>

Este archivo de encabezado es equivalente al #include<stdio.h> que aprendimos en lenguaje C. Se usa para entrada y salida a nuestra consola. Se menciona brevemente aquí y se analiza en detalle más adelante.

  • Además del archivo de encabezado anterior, también existe esta línea de código: usando el espacio de nombres std;

espacio de nombres es la primera palabra clave que queremos usar en C++, es espacio de nombres.

En C/C++, hay una gran cantidad de variables, funciones y clases que se aprenderán más adelante. Los nombres de estas variables, funciones y clases existirán en el ámbito global, lo que puede causar muchos conflictos. El propósito de utilizar espacios de nombres es localizar los nombres de los identificadores para evitar conflictos de nombres o contaminación de nombres . La palabra clave namespace parece solucionar este problema.

1. Conflicto de nombres en lenguaje C

 Antes de presentar oficialmente el espacio de nombres, revisemos el problema del conflicto de nombres en lenguaje C:

#include<stdio.h>
//命名冲突
int rand = 0;
int main()
{
	printf("%d", rand);
	return 0;
}

En el código anterior, solo usamos intclude<stdio.h> para el archivo de encabezado y nada más. Definimos la variable global rand y el código se compila normalmente sin errores.

Pero debes saber que hay una función de biblioteca en lenguaje C que es rand, pero debes incluir el archivo de encabezado #include<stdlib.h>, incluir este archivo de encabezado e intentar ejecutar nuevamente:

Obviamente hay un conflicto de nombres aquí: la variable global rand que definimos entra en conflicto con la función rand en la biblioteca.

Es muy sencillo resolver este problema. Algunas personas pueden decir que simplemente puedo cambiar el nombre de la variable. De hecho es posible, pero no es una solución a largo plazo. Si uso la variable más de 100 veces sin saberlo, ¿Quieres una modificación A? Esto refleja completamente el conflicto de nombres del lenguaje C.

En C++, el espacio de nombres introducido resuelve muy bien el problema del conflicto de nombres del lenguaje C.

2. Definición del espacio de nombres

Para definir un espacio de nombres, debe usar la palabra clave namespace, seguida del nombre del espacio de nombres y luego seguido de un par de {}. Los miembros en {} son los miembros del espacio de nombres.

como sigue:

 Dos variables idénticas no pueden aparecer en el mismo alcance . En este momento, rand está bloqueado en el dominio del espacio de nombres de n1 y aislado de otras cosas. Por lo tanto, no se producirá ningún conflicto de nombres cuando se expanda el archivo de encabezado stdlib.h. En este momento, la impresión de rand es la dirección de rand en la función de la biblioteca, rand es un puntero de función y se imprime la dirección.

Otro ejemplo:

Este código refleja más completamente que agregar un espacio de nombres no solo puede evitar conflictos de nombres, sino que también nos dice que al acceder a las variables m, cyf en este momento, se accede a todas en el dominio global y al dominio del espacio de nombres xzy. el interior y el dominio global establecen un muro y no interfieren entre sí. Sin embargo, aquí c y m siguen siendo variables globales y el espacio de nombres no afecta el ciclo de vida .

Los espacios de nombres tienen tres características principales:

  • 1. El espacio de nombres puede definir variables, funciones y tipos.
//1. 普通的命名空间
namespace N1 // N1为命名空间的名称
{
	// 命名空间中的内容,既可以定义变量,也可以定义函数,也可以定义类型
	int a; //变量
	int Add(int left, int right) //函数
	{
		return left + right;
	}
    struct ListNode //类型
    {
        int val;
        struct ListNode* next;
    }
 
}
  • 2. Los espacios de nombres se pueden anidar
//2. 命名空间可以嵌套
namespace N2
{
	int a;
	int b;
	int Add(int left, int right)
	{
		return left + right;
	}
	namespace N3
	{
		int c;
		int d;
		int Sub(int left, int right)
		{
			return left - right;
		}
	}
}
  • 3. Se permite que existan varios espacios de nombres con el mismo nombre en el mismo proyecto y el compilador eventualmente los sintetizará en el mismo espacio de nombres.
//3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
namespace N1
{
	int Mul(int left, int right)
	{
		return left * right;
	}
}

3. Uso del espacio de nombres

Todos sabemos que en el lenguaje C existen reglas de precedencia locales, como las siguientes:

int a = 0; //全局域
int main()
{
	int a = 1; //局部域
	printf("%d\n", a); // 1 局部优先
	return 0;
}

Todos sabemos que el resultado aquí es 1, pero ¿qué pasa si tengo que imprimir un en el dominio global?

Esto introduce el calificador de alcance de dominio ::  ), y el efecto es el siguiente:

Con la adición de (  :  :), el dominio al que se accede en este momento es el dominio global. La razón por la que es el dominio global es que el frente de "  :: " está en blanco. Si está en blanco, entonces el dominio global se accede Si lo miras de esta manera, I Si reemplazas el dominio del espacio de nombres delante de "  :: ", puedes acceder al contenido en el dominio del espacio de nombres. De hecho, "  :: " es una forma de utilizar el espacio de nombres.

 Por ejemplo, definimos el siguiente espacio de nombres:

namespace n1 
{
	int f = 0;
	int rand = 0;
}

Ahora, ¿cómo accedemos al contenido del dominio del espacio de nombres? En realidad hay 3 maneras:

  1. Agregue el nombre del espacio de nombres y el calificador de alcance "  :: ";
  2. Utilice el espacio de nombres para expandir todos los nombres de los espacios de nombres;
  3. Utilice el uso para expandir los miembros en el espacio de nombres.
  • 1. Agregue el espacio de nombres y el calificador de alcance "::"
int main()
{
	printf("%d\n", n1::f); //0
	printf("%d\n", n1::rand);//0
	return 0;
}

Para evitar que se defina la misma variable o tipo, podemos definir múltiples espacios de nombres para evitarlo.

namespace ret
{
	struct ListNode
	{
		int val;
		struct ListNode* next;
	};
}
 
namespace tmp
{
	struct ListNode
	{
		int val;
		struct ListNode* next;
	};
	struct QueueNode
	{
		int val;
		struct QueueNode* next;
	};
}

Cuando queremos usarlos, es el siguiente:

int main()
{
	struct ret::ListNode* n1 = NULL;
	struct tmp::ListNode* n2 = NULL;
	return 0;
}

Para el anidamiento de espacios de nombres, de la siguiente manera:

 Se puede acceder así:

int main()
{
	struct tx::List::Node* n1; //访问List.h文件中的Node
	struct tx::Queue::Node* n2;//访问Queue.h文件中的Node
}

Pero el método de acceso anterior es demasiado engorroso , ¿puedes omitir algunas repeticiones? Por ejemplo, en lugar de escribir tx::, aquí viene el segundo método de acceso al espacio de nombres:

  • 2. Utilice el espacio de nombres para expandir todos los nombres de los espacios de nombres.
using namespace tx;

Esta oración significa liberar las cosas definidas en el espacio de nombres tx, para que podamos acceder a él de esta manera:

int main()
{
	struct List::Node* n1; //访问List.h文件中的Node
	struct Queue::Node* n2;//访问Queue.h文件中的Node
}

Por supuesto, también puedo eliminar otra capa, de la siguiente manera:

using namespace tx;
using namespace List;
int main()
{
	struct Node* n1; //访问List.h文件中的Node
	struct Queue::Node* n2;//访问Queue.h文件中的Node
}

Al expandir, tenga en cuenta que el orden de tx y List no se puede invertir.

Este método de acceso puede lograr un efecto simplificado, pero también existe un cierto riesgo: todos los espacios de nombres se liberan y regresan los conflictos de nombres .

 Por lo tanto, las cuestiones específicas de conflicto de nombres deben discutirse por separado:

De esto aprendemos que no es bueno ampliarlo todo, hay que pedirlo a la carta y ampliar lo que utilizamos, lo que lleva al tercer método de uso.

  • 3. Utilice el uso para expandir los miembros en el espacio de nombres.

Para el código anterior, solo ponemos f:

namespace n1
{
	int f = 0;
	int rand = 0;
}
using n1::f;
int main()
{
	f += 2;
	printf("%d\n", f);
	n1::rand += 2;
	printf("%d\n", n1::rand);
}
  • Echemos un vistazo al espacio de nombres de la biblioteca estándar de C++:
#include<iostream>
using namespace std; //std 是封C++库的命名空间
int main()
{
	cout << "hello world" << endl; // hello world
	return 0;
}

Si omite esta línea de código: usando namespace std;

Si desea generar hola mundo, haga esto:

#include<iostream>
int main()
{
	std::cout << "hello world" << std::endl;
	return 0;
}

Por supuesto también puede ser así:

#include<iostream>
using std::cout;
int main()
{
	cout << "hello world" << std::endl;
	return 0;
}

Esto hace un uso completo de los espacios de nombres.

 

Supongo que te gusta

Origin blog.csdn.net/m0_49687898/article/details/131350690
Recomendado
Clasificación