2012-06-07 22 views
14

asume que he declarado una función (o clase, no importa) en un archivo de cabecera, que es parte del espacio de nombres foo:Mejores prácticas: ¿usar espacio de nombres o volver a abrir el espacio de nombres?

namespace foo 
{ 
    void bar(); 
    … 
} 

Durante mucho tiempo he estado volver a abrir el espacio de nombres cuando fue la definición de la función en un archivo CPP:

namespace foo 
{ 
void bar() 
{ 
    doSomething(); 
    … 
} 
} 

Eso es porque he aprendido de esta manera y fue usado en un proyecto en el que estaba trabajando. Realmente nunca a pesar de ello, hasta hace poco, cuando me topé con un proyecto que utiliza la directiva using en su lugar:

using namespace foo; 

void bar() 
{ 
    doSomething(); 
    … 
} 

Finalmente hay una opción de utilizar el nombre completo. Me parece bastante tedioso, especialmente cuando se trata de clases con muchos miembros. En mi opinión, no tiene mucho sentido cuando todo el contenido del archivo es parte de un espacio de nombres.

void foo::bar() 
{ 
    doSomething(); 
    … 
} 

Así que mi pregunta es ¿cuál debería preferirse y por qué? Especialmente con respecto a las dos primeras opciones (usar el espacio de nombres de directiva frente a reabrir).

+3

Yo diría que es una cuestión de preferencia personal.Yo mismo uso una combinación de la primera y la última de tus alternativas. –

+5

Acepto que es una cuestión de preferencia personal. 'foo :: bar' es repetitivo pero greppable, aunque eso podría ser irrelevante si las personas solo buscan en su fuente usando un IDE. –

+2

Es como preguntar si es mejor usar pestañas o 4 espacios. ** No te preocupes por las cosas pequeñas. ** :) – LihO

Respuesta

13

creo que la manera más limpia se vuelve a abrir el espacio de nombres, y tengo los argumentos para apoyarla:

  • con su segunda opción, con la directiva using, no está claro que está implementando un método en ese espacio de nombres. También podría estar implementando una función gratuita que utiliza algo del espacio de nombres.
  • la tercera opción se usa generalmente para implementar funciones de miembro de clase. Si mira directamente en el archivo cpp, no está claro si está implementando una función desde un espacio de nombres a menos que sepa que existe espacio de nombres. Lo primero que viene a la mente es que está implementando una función de miembro de la clase.
  • el primero es el más claro. Abre el espacio de nombres y define una función dentro de él. La función es parte del espacio de nombres, y esta es la implementación.
+0

Tu segundo punto parece decir: "No hago X, por lo tanto, lo primero que me viene a la mente es S". Y no necesariamente viene primero a la mente de las personas que hacen X, así que una vez que sigas la convención, el problema desaparece. Además, si no puede distinguir entre nombres de nombres de grupos y nombres de clases, considere elegir mejores nombres ;-p. –

+0

@SteveJessop No creo que ese sea un punto válido. 'X :: foo()' es la * única * forma en que puede definir un método de clase (a menos que esté en línea). Mientras que para los espacios de nombres tienes una alternativa. Entonces, ¿por qué usar dos estilos para representar cosas diferentes, cuando puedes usar diferentes estilos con intención clara? –

+1

parece haber aquí un axioma subyacente, que es de vital importancia hacer que diferentes cosas se vean tan diferentes como sea posible. Creo que otras cosas pueden ser más importantes, así que no acepto ese axioma (si lo hiciera usaría C, ya que no tiene sobrecarga de funciones). –

6

Aunque using namespace es la solución más lenta (y por lo tanto la más tentadora), a menudo no es una buena idea. Además de lo que dice Luchian sobre declaraciones de funciones ambiguas (alguien nuevo en el proyecto no sabría si esa es una función independiente o una en el espacio de nombres), y el hecho de que podría introducir un nombre en el espacio de nombres más tarde, chocando con uno usando ahora, tengo otra razón por la que sugeriría usar el tercer método.

Usando el tercer método, le da a su código más consistencia. Si A está dentro de B, siempre lo definiría con A::B. Si A es una clase y B una función en la clase, escribiría type A::B(args). Si A es una clase y B es un miembro estático, volvería a escribir type A::B = value. Ahora A es un espacio de nombres, pero sigue siendo el mismo concepto: B se define dentro de A, por lo tanto, es más coherente volver a utilizar A::B.

(No es una ventaja añadida de capacidad de búsqueda si su editor es, por ejemplo, VIM)

Cuestiones relacionadas