¿Por qué se utilizan espacios de nombres sin nombre y cuáles son sus beneficios?
Acabo de unirme a un nuevo proyecto de software C++ y estoy tratando de entender el diseño. El proyecto hace uso frecuente de espacios de nombres sin nombre. Por ejemplo, algo como esto puede ocurrir en un archivo de definición de clase:
// newusertype.cc
namespace {
const int SIZE_OF_ARRAY_X;
const int SIZE_OF_ARRAY_Y;
bool getState(userType*,otherUserType*);
}
newusertype::newusertype(...) {...
¿Cuáles son las consideraciones de diseño que podrían hacer que uno utilice un espacio de nombres sin nombre? ¿Cuáles son las ventajas y desventajas?
Los espacios de nombres sin nombre son una utilidad para hacer local una unidad de traducción de identificadores . Se comportan como si elegirías un nombre único por unidad de traducción para un espacio de nombres:
namespace unique { /* empty */ }
using namespace unique;
namespace unique { /* namespace body. stuff in here */ }
El paso adicional que utiliza el cuerpo vacío es importante, por lo que ya puede hacer referencia dentro del cuerpo del espacio de nombres a identificadores como::name
los que están definidos en ese espacio de nombres, ya que la directiva de uso ya tuvo lugar.
Esto significa que puede tener funciones gratuitas llamadas (por ejemplo) help
que pueden existir en múltiples unidades de traducción y no entrarán en conflicto en el momento del enlace. El efecto es casi idéntico al uso de la static
palabra clave utilizada en C que puede incluirse en la declaración de identificadores. Los espacios de nombres sin nombre son una alternativa superior, pudiendo incluso convertir una unidad de traducción de tipos en local.
namespace { int a1; }
static int a2;
Ambos a
son unidades de traducción locales y no chocarán en el momento del enlace. Pero la diferencia es que ela1
en el espacio de nombres anónimo obtiene un nombre único.
Lea el excelente artículo en comeau-computing ¿Por qué se utiliza un espacio de nombres sin nombre en lugar de estático? ( Espejo de Archive.org ).
Tener algo en un espacio de nombres anónimo significa que es local para esta unidad de traducción (archivo .cpp y todos sus incluidos). Esto significa que si se define otro símbolo con el mismo nombre en otro lugar, no habrá una violación de la regla de definición única (ODR).
Esto es lo mismo que la forma C de tener una variable global estática o una función estática, pero también se puede usar para definiciones de clases (y debe usarse en lugar de static
en C++).
Todos los espacios de nombres anónimos en el mismo archivo se tratan como el mismo espacio de nombres y todos los espacios de nombres anónimos en archivos diferentes son distintos. Un espacio de nombres anónimo es el equivalente a:
namespace __unique_compiler_generated_identifer0x42 {
...
}
using namespace __unique_compiler_generated_identifer0x42;