usando namespace std; en un archivo de cabecera

Entonces, tengo lo siguiente en un archivo de especificación

#include  #include  using namespace std: class MyStuff { private: string name; fstream file; // other stuff public: void setName(string); } 

También tengo en el archivo de implementación

 #include "MyStuff.h" using namespace std; void MyStuff::setName(string name); { name = name } 

y en el archivo de progtwig tengo …

 #include  #include  using namespace std; void main() { string name; MyStuff Stuff; cout << "Enter Your Name: "; getline(cin, name); Stuff.setName(name); } 

Y estoy recostackndo esa aplicación “using namespace std;” en un archivo de encabezado es un no-no, y eso para calificar completamente es la “mejor” práctica; como std::cout << stuff << endl;

Entiendo que para usar una cadena, debe tener el espacio de nombre estándar. ¿Es eso cierto?

Si es así, en el archivo de encabezado, es más “puro / limpio” para hacerlo como …

 #include  class MyStuff { std::string name; } 

Y, como lo entiendo actualmente, usando namespace std; en los tres archivos, especificación, implementación y progtwig, esencialmente capas los tres espacios de nombres uno encima del otro, por lo que si declaro por separado el string name; dentro de cada uno de los archivos, el comstackdor no sabrá qué va a qué. ¿Es eso cierto?

En general, entiendo que ser claro es algo “bueno” que hacer, sin embargo no estoy muy claro sobre la especificidad de cómo hacerlo, y estoy más interesado en el “por qué” más profundo que subyace a todo.

Entonces, mi pregunta directa es, en mi ejemplo proporcionado, ¿cuál es la forma “más clara” de describir la función tanto para el comstackdor como para el “estándar” de la industria? Y, ¿puede dirigirme a recursos que delineen más claramente el razonamiento y la implementación práctica de espacios de nombres?

Digamos que declaro una string clase yo mismo. Debido a que soy un vago vago, lo hago en el espacio de nombres global.

 // Solar's stuff class string { public: string(); // ... }; 

Algún tiempo después, me doy cuenta de que reutilizar parte de tu código beneficiaría mi proyecto. Gracias a que lo conviertes en código abierto, puedo hacerlo:

 #include  #include  string foo; 

Pero de repente el comstackdor ya no me quiere. Como hay una ::string (mi clase) y otra ::string (la estándar, incluida por su encabezado y llevada al espacio de nombres global con el using namespace std; ), hay todo tipo de dolor.

Peor aún, este problema se promueve a través de cada archivo que incluye mi encabezado (que incluye su encabezado, que … se entiende la idea).

Sí, lo sé, en este ejemplo también tengo la culpa de no proteger mis propias clases en mi propio espacio de nombres, pero esa es la que se me ocurrió ad-hoc.

Los espacios de nombres están ahí para evitar choques de identificadores. Su encabezado no solo introduce MyStuff en el espacio de nombres global, sino también en todos los identificadores de string y fstream . Es probable que la mayoría de ellos nunca sean realmente necesarios para ninguno de nosotros, entonces ¿por qué arrastrarlos a lo global, contaminando el medio ambiente?

Además: desde la vista de un progtwigdor / depurador de mantenimiento, foo::MyStuff es diez veces más conveniente que MyStuff , espacio de nombres en otro lugar (probablemente ni siquiera el mismo archivo fuente), porque obtienes la información del espacio de nombres justo en el punto en el código donde lo necesitas.

Múltiples instancias de using namespace std; de using namespace std; no causará ninguna ambigüedad. El problema es que esa statement importa todos los nombres / tipos / funciones de std en su espacio de nombres, y ahora si quiere nombrar una string clase por ejemplo, tendrá problemas. Esto es más probable que suceda con funciones como eliminar, borrar, etc.

El uso de ella en los encabezados es un nivel peor porque eso se propaga a todos los .cpp s ese encabezado, sin la conciencia de la persona que lo incluye. .cpp uso en .cpp menos necesita una elección consciente.

Se puede obtener una explicación más completa en Why ¿”usar namespace std” se considera una mala práctica?

Puede encontrar un ejemplo de problemas que pueden surgir de esto en Cómo usar un iterador? donde OP define una distance función y sigue obteniendo la respuesta incorrecta. Otro ejemplo en Confusion sobre punteros y referencias en C ++

Los usos del espacio de nombres son para su conveniencia, no para que inflija a otros: nunca escriba una statement de uso o una directiva de uso antes de una directiva #include.

Corolario: en archivos de encabezado, no escriba el nivel de espacio de nombres usando directivas o usando declaraciones; en su lugar, califica explícitamente el nombre del espacio de nombres de todos los nombres. (La segunda regla se sigue de la primera, porque los encabezados nunca pueden saber qué otro header #includes podría aparecer después de ellos).

En general, entiendo que ser claro es algo “bueno” que hacer, sin embargo no estoy muy claro sobre la especificidad de cómo hacerlo, y estoy más interesado en el “por qué” más profundo que subyace a todo.

Debajo de los fragmentos de código se refleja por qué el uso del using namespace de using namespace en el archivo de encabezado es malo:

 // snippet 1 namespace A { int f(double); } // snippet 2 namespace B { using A::f; void g(); } // snippet 3 namespace A { int f(int); } // snippet 4 void B::g() { f(1); // which overload is called? } 

Entonces en tu ejemplo, simplemente este es mejor:

 #include  class MyStuff { std::string name; }; 

Recomendar libro: Normas de encoding C ++: 101 Reglas, directrices y mejores prácticas

y enlace: guía de encoding de Google C ++

Intereting Posts