sintaxis paquetes paquete organizacion nombre nombrar funciones ejemplos como java c++ namespaces packages

organizacion - paquetes java pdf



Espacios de nombres C++, comparaciĆ³n con paquetes Java (7)

Aquí hay algunas razones por las cuales y cómo los espacios de nombres C ++ son diferentes a los espacios de nombres Java o C #.

Evitando conflictos

En los lenguajes Java / C #, los espacios de nombres están destinados a evitar conflictos entre nombres en diferentes partes de las bibliotecas de clases. Puede tener una clase llamada "Vigilante" en 5 lugares diferentes en la jerarquía del espacio de nombres en C #. En C ++, si tiene las mismas clases con nombre que aparecen en su biblioteca, coloca dentro de otra clase en lugar de crear espacios de nombres. Dichas clases anidadas están todas bien y animadas y, de hecho, la sintaxis también se trata como si la clase es un espacio de nombres que utiliza el operador ::.

¿Cuántos espacios de nombres anidados debería haber?

Las bibliotecas populares como Boost, Eigen y, por supuesto, STL proporcionan buenos ejemplos. estas bibliotecas suelen tener casi todo incluido en un espacio de nombres como std:: o boost:: o eigen:: . Pocos componentes obtienen su propio espacio de nombres como std::ios o boost:filesystem . No hay reglas consistentes sobre cuándo usar el segundo nivel, pero parece ser grande o los componentes desarrollados / mantenidos por separado u opcionales suelen tener sus propios espacios de nombres. El tercer nivel es aún más raro. En general, utilizo el company::project structure company::project y para el subsistema grande de uso independiente del proyecto company::project::component .

Evitar conflictos en bibliotecas externas

Ahora la gran pregunta: ¿qué pasa si obtienes dos bibliotecas de dos personas diferentes que tienen exactamente los mismos espacios de nombres y clases? Esta situación es bastante rara porque la mayoría de la gente tiende a envolver sus bibliotecas al menos en el nombre de su proyecto. Incluso si los nombres de los proyectos son los mismos, es aún más raro que termine usando bibliotecas de ambos. Sin embargo, a veces se toman malas decisiones para los nombres de los proyectos (ahm ... "metro", "apollo" ...) o incluso los espacios de nombres simplemente no se utilizan en absoluto. Si eso sucede, ajuste #include para una o ambas bibliotecas en un espacio de nombres y se resuelve el conflicto. Esta es una razón por la cual las personas no se preocupan demasiado por los conflictos porque resolverlos es trivial. Si sigues la práctica de usar company::project , los conflictos se vuelven súper raros.

Diferencias en idiomas

Aunque C ++ proporciona el using namespace declaración de using namespace como C #, generalmente se considera una mala práctica para "importar" todo en su propio espacio de nombres. La razón de esto es que un encabezado puede contener muchas cosas "malas", incluida la redefinición de elementos que pueden sorprenderte por completo. Esto es bastante diferente de C # / Java donde solo obtiene una interfaz pública limpia cuando hace el equivalente al using namespace de using namespace . (nota al margen: en C ++ puedes lograr lo mismo usando el patrón Pimpl, pero normalmente es demasiado de fontanería adicional y pocas bibliotecas realmente lo hacen). Entonces casi nunca quieres using namespace . En cambio, usted escribe typedefs (o using name = ) para lo que realmente quiere usar. De nuevo, esto hace que los espacios de nombres profundamente anidados sean poco prácticos de usar.

Código de organización

En Java / C #, las personas tienden a organizar el código en carpetas mucho. Normalmente, a medida que la carpeta crece más de 20 o incluso 10 archivos, las personas comenzarían a pensar en las carpetas. En C ++, las cosas son más diversas, pero para muchos proyectos grandes se prefieren estructuras de directorios más planas. Por ejemplo, la carpeta estándar de la biblioteca estándar tiene 53 archivos y el proyecto folly de Facebook parece seguir la misma ruta. Creo que una razón para esto es probablemente el hecho de que los usuarios de Java / C # usan IDEs visuales más y usan desplazamientos del mouse en la navegación de carpetas en oposición a la consola donde pueden usar comodines para buscar archivos en una estructura plana. Además, los programadores de C ++ absolutamente no evitan poner múltiples clases en un solo archivo y nombrar el archivo como unidad lógica en lugar de como nombre de clase a diferencia de C # o Java. Esto hace que la compilación sea más rápida, lo que es muy importante para proyectos grandes. Si bien no existe un requisito de nivel de idioma para tener su propio espacio de nombres para cada carpeta, muchos desarrolladores de C ++ prefieren asignar su propio espacio de nombres a cada carpeta y mantener la jerarquía de carpetas de 2 o menos niveles de profundidad.

Posible excepción

En C ++ puede referirse a A::B::C::D simplemente como C::D si ya está dentro de A::B Por lo tanto, si tiene un código privado o clases menos utilizadas que desea presionar más hacia abajo, puede hacerlo mientras mantiene su propia profundidad relativa en 2 o más. En este caso, es posible que también desee crear una carpeta para cada nivel solo para que las ubicaciones de los archivos sean predecibles. En general, no hay estándares dorados en esta área, pero no desea excederse con espacios de nombres anidados profundamente que imitan C # / Java.

Relacionado

Recientemente hice un montón de codificación Java y me he acostumbrado a sistemas de nombres de paquetes muy específicos, con anidamiento profundo, por ejemplo com.company.project.db . Esto funciona bien en Java, AS3 / Flex y C #. He visto el mismo paradigma aplicado también en C ++, pero también he oído que es malo ver los espacios de nombres de C ++ como contrapartidas directas de los paquetes de Java.

¿Es eso cierto y por qué? ¿En qué se parecen y se diferencian los espacios de nombres / paquetes? ¿Qué problemas se verán si usa espacios de nombres anidados?


Creo que falta algo en las respuestas anteriores, y es una de las razones por las que realmente me gusta C ++.

Imagine que está programando una aplicación gráfica y de repente se da cuenta de que hay algo común entre todos sus widgets. Desea que todos ellos tengan una nueva función. ¿Qué haces?

1) ¿Edita la clase de widget base? OK, pero lo más probable es que no tengas acceso a él. Tal vez haya un problema de licencia que le impide hacer su propia modificación. Incluso si puede hacerlo, si es algo que solo tiene sentido para su proyecto, los autores no lo incluirán en su versión futura, y la actualización del kit de herramientas será más dolorosa.

2) ¿Crear una clase de interfaz / multi-herencia? Dependiendo de su código actual, será más o menos doloroso actualizar cada clase relacionada con un widget. Haga esto y le costará más mantener su código porque todos los que definen una nueva clase deben saber que se supone que heredarán de su interfaz. Ser dependiente de la disciplina de otras personas es realmente arriesgado.

Lo maravilloso de los espacios de nombres C ++ aquí es que tienes una forma extra de encapsular cosas dentro de un sistema ya existente. No solo puede encapsular dentro de bibliotecas existentes que no puede editar, puede encapsular conceptos similares que no puede insertar fácilmente en su jerarquía de clases / objetos.

Java te obliga a concentrarte más en un diseño POO puro. Seguro que te digo que puede ser un truco sucio y no elegante, pero hay mucha gente perezosa que no dedica tiempo a arreglar sus diseños.


En C ++, la unidad básica de diseño e implementación es la clase, no el espacio de nombres. Los espacios de nombres estaban destinados a prevenir los conflictos de nombres en bibliotecas grandes, no a expresar conceptos.

Las clases tienen varias ventajas sobre los espacios de nombres:

  • pueden tener constructores y destructores
  • ellos pueden tener miembros privados
  • no pueden ser reabiertos

Sin embargo, miraría dos veces a cualquier relación profundamente anidada. Esa no es realmente una buena forma de diseñar software, y conduce a un código ilegible, ya sea que utilice clases o espacios de nombres.


En C ++, los espacios de nombres están a punto de particionar los nombres disponibles. Los paquetes de Java son sobre módulos. La jerarquía de nombres es solo uno de sus aspectos.

No hay nada de malo, per se, con espacios de nombres profundamente anidados en C ++, excepto que normalmente no son necesarios ya que no hay un sistema de módulos detrás de ellos, y las capas adicionales solo agregan ruido. Por lo general, es suficiente tener uno o dos niveles de espacio de nombres, con un nivel extra extraño para los detalles internos (a menudo simplemente llamado Detalles).

También existen reglas adicionales para espacios de nombres C ++ que pueden atraparlo si se usan en exceso, como argument-dependent-lookup y las reglas para resolver los niveles principales. WRT este último, toma:

namespace a{ namespace b{ int x; } } namespace b{ string x; } namespace a { b::x = 42; }

Es esto legal? ¿Es obvio lo que está pasando? Necesita saber la precendencia de la resolución del espacio de nombres para responder esas preguntas.


Escribiré un par de cosas que he escuchado pero no sé la veracidad de, por favor ayuda a confirmar / disiparlas.

  1. El rendimiento de C ++ está (de alguna manera) afectado por los nombres largos de los métodos totalmente especificados, por ejemplo, namespace1::namespace2::namespace3::classX::method123()

  2. Puede llegar a un límite en la longitud del símbolo permitido en el compilador / vinculador


Los paquetes de Java no están anidados, son planos. Cualquier anidación aparente no es más que una convención de nomenclatura.

Por ejemplo, el paquete com.company.project.db no tiene ninguna relación con com.company.project o com.company.project.db.x . El código en com.company.project.db no tiene más acceso al código en com.company.project.db.x que el código en abc .


Puede tener espacios de nombres anidados en C ++.

Sin embargo, no funcionan igual que en Java, obviamente. Los paquetes Java están mucho mejor definidos y no existe una rareza de inicio estático real. Con los espacios de nombres C ++ son útiles, pero aún tienen un poco de peligro involucrado.