Probablemente un duplicado, pero no fácil de buscar ...
Dado un encabezado como:
namespace ns1
{
class MyClass
{
void method();
};
}
Lo he visto method()
definido de varias maneras en el archivo .cpp:
Versión 1:
namespace ns1
{
void MyClass::method()
{
...
}
}
Versión 2:
using namespace ns1;
void MyClass::method()
{
...
}
Versión 3:
void ns1::MyClass::method()
{
...
}
¿Existe una forma "correcta" de hacerlo? ¿Alguno de estos es "incorrecto" en el sentido de que no todos significan lo mismo?
c++
coding-style
namespaces
Señor chico
fuente
fuente
Respuestas:
La versión 2 no es clara y no es fácil de entender porque no sabe qué espacio de nombres
MyClass
pertenece y es simplemente ilógico (¿la función de clase no está en el mismo espacio de nombres?)La versión 1 es correcta porque muestra que en el espacio de nombres, está definiendo la función.
La versión 3 también es correcta porque usó el
::
operador de resolución de alcance para hacer referencia aMyClass::method ()
en el espacio de nombresns1
. Prefiero la versión 3.Consulte Espacios de nombres (C ++) . Esta es la mejor forma de hacer esto.
fuente
namespace N {struct X { void f(); }; X operator==( X const &, X const & ); }
, ahora en el archivo cpp con la instrucción using puede definir la función miembro comovoid X::f() {}
, pero si defineX operator==(X const&, X const&)
estará definiendo un operador diferente al definido en el encabezado (tendrá que usar 1 o 3 para la función gratuita allí).5 años después y pensé en mencionar esto, que se ve bien y no es malo
fuente
Estoy usando la versión 4 (a continuación) porque combina la mayoría de las ventajas de la versión 1 (la concisión de la definición resoectiva) y la versión 3 (sea máximamente explícita). La principal desventaja es que la gente no está acostumbrada pero como lo considero técnicamente superior a las alternativas no me importa.
Versión 4: use la calificación completa usando alias de espacio de nombres:
En mi mundo, con frecuencia uso alias de espacios de nombres ya que todo está calificado explícitamente, a menos que no pueda (por ejemplo, nombres de variables) o sea un punto de personalización conocido (por ejemplo, swap () en una plantilla de función).
fuente
outer
yinner
definidos como espacios de nombres en otros archivos de encabezado?La versión 3 hace que la asociación entre la clase y el espacio de nombres sea muy explícita a expensas de escribir más. La versión 1 evita esto pero captura la asociación con un bloque. La versión 2 tiende a ocultar esto, así que evitaría esa.
fuente
La Guía de estilo de Googles C ++ dicta su versión 1, aunque sin sangría.
fuente
Elijo Num.3 (también conocida como la versión detallada). Es más mecanografiado, pero la intención es exacta para ti y para el compilador. El problema que publicaste tal cual es en realidad más simple que el mundo real. En el mundo real, existen otros ámbitos para las definiciones, no solo los miembros de la clase. Sus definiciones no son muy complicadas solo con clases, porque su alcance nunca se vuelve a abrir (a diferencia de los espacios de nombres, el alcance global, etc.).
Num.1, esto puede fallar con ámbitos que no sean clases, cualquier cosa que se pueda volver a abrir. Por lo tanto, puede declarar una nueva función en un espacio de nombres utilizando este enfoque, o sus líneas pueden terminar siendo sustituidas a través de ODR. Lo necesitará para algunas definiciones (en particular, especializaciones de plantillas).
Num.2 Esto es muy frágil, particularmente en bases de código grandes - a medida que cambian los encabezados y las dependencias, su programa no podrá compilarse.
Núm.3 Esto es ideal, pero hay mucho que escribir: cuál es su intención de definir algo . Esto hace exactamente eso, y el compilador se activa para asegurarse de que no haya cometido un error, una definición no esté desincronizada con su declaración, etc.
fuente
Resulta que no es sólo "cuestión de estilo de codificación". Num. 2 conduce a un error de vinculación al definir e inicializar una variable declarada externa en el archivo de encabezado. Eche un vistazo al ejemplo de mi pregunta. Definición de constante dentro del espacio de nombres en el archivo cpp
fuente
Todos los caminos son correctos y cada uno tiene sus ventajas y desventajas.
En la versión 1, tiene la ventaja de no tener que escribir el espacio de nombres delante de cada función. La desventaja es que obtendrá una identificación aburrida, especialmente si tiene más de un nivel de espacios de nombres.
En la versión 2, hace que su código sea más limpio, pero si tiene más de un espacio de nombres implementado en el CPP, uno puede acceder a las funciones y variables del otro directamente, haciendo que su espacio de nombres sea inútil (para ese archivo cpp).
En la versión 3, tendrá que escribir más y sus líneas de función pueden ser más grandes que la pantalla, lo cual es malo para los efectos de diseño.
También hay otra forma en que algunas personas lo usan. Es similar a la primera versión, pero sin problemas de identificación.
Es como esto:
Depende de usted elegir cuál es mejor para cada situación =]
fuente
#ifdef
cláusula.#define OPEN_NS(X)
, creo que es un poco útil, pero no realmente ... No me opongo a las macros, pero esto parece un poco OTT. Creo que el enfoque de Dietmar Kühl es mejor para los espacios de nombres anidados.