Creación de un espacio de nombres de C++ en el encabezado y la fuente (cpp)

4 minutos de lectura

avatar de usuario
enlaces77

¿Hay alguna diferencia entre envolver el contenido del archivo de encabezado y cpp en un espacio de nombres o envolver solo el contenido del encabezado y luego hacer usando el espacio de nombres en el archivo cpp?

Por diferencia me refiero a cualquier tipo de penalización de rendimiento o semántica ligeramente diferente que pueda causar problemas o cualquier cosa que deba tener en cuenta.

Ejemplo:

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
namespace X
{
  void Foo::TheFunc()
  {
    return;
  }
}

contra

// header
namespace X
{
  class Foo
  {
  public:
    void TheFunc();
  };
}

// cpp
using namespace X;
{
  void Foo::TheFunc()
  {
    return;
  }
} 

Si no hay diferencia, ¿cuál es la forma preferida y por qué?

avatar de usuario
Roee Gavirel

La diferencia entre “espacio de nombres X” y “usar espacio de nombres X” es que en el primero, cualquier declaración nueva estará bajo el espacio de nombres, mientras que en el segundo no.

En su ejemplo, no hay una nueva declaración, por lo que no hay diferencia, por lo tanto, no hay una forma preferida.

  • Depende del proyecto y estilo. A menudo hay un espacio de nombres principal para una carga de archivos en un módulo y el segundo estilo tiene sentido.

    – Nicolás Wilson

    21 de noviembre de 2011 a las 11:43

avatar de usuario
vprajan

El espacio de nombres es solo una forma de manipular la firma de la función para que no entren en conflicto. Algunos prefieren la primera forma y otros prefieren la segunda versión. Ambas versiones no tienen ningún efecto sobre el rendimiento del tiempo de compilación. Tenga en cuenta que los espacios de nombres son solo una entidad de tiempo de compilación.

El único problema que surge con el uso del espacio de nombres es cuando tenemos los mismos nombres de espacios de nombres anidados (es decir) X::X::Foo. Hacer eso crea más confusión con o sin el uso de palabras clave.

No hay penalizaciones de rendimiento, ya que el resultado podría ser el mismo, pero poniendo su Foo en el espacio de nombres implícitamente introduce ambigüedad en caso de que tenga Foos en diferentes espacios de nombres. Puede obtener su código fubar, de hecho. Recomiendo evitar el uso using para este propósito.

Y tienes un perro callejero { después using namespace 😉

  • No lo llamaría extraviado, ya que coincide con el cierre. } al final. Sin embargo, llamaría redundante a ese par de llaves;)

    – blubberdiblub

    14 de junio de 2017 a las 17:48

  • @blubberdiblub, la pregunta fue editada, si revisó la versión original, usted haría llamalo extraviado 😉

    – Michael Krelin – hacker

    14/06/2017 a las 21:22

Si está intentando usar variables de una a otra, le recomiendo externalizarlas y luego inicializarlas en el archivo fuente de la siguiente manera:

// [.hh]
namespace example
{
   extern int a, b, c;
}
// [.cc]
// Include your header, then init the vars:
namespace example
{
   int a, b, c;
}
// Then in the function below, you can init them as what you want: 
void reference
{
    example::a = 0;
}

Si el segundo también compila, no debería haber diferencias. Los espacios de nombres se procesan en tiempo de compilación y no deberían afectar las acciones de tiempo de ejecución.

Pero por cuestiones de diseño, la segunda es horrible. Incluso si compila (no estoy seguro), no tiene ningún sentido.

  • No creo que compile, pero no porque haya una diferencia, sino porque hay un extraviado. { 😉

    – Michael Krelin – hacker

    21 de noviembre de 2011 a las 11:24

  • La diferencia es que Foo::TheFunc() se declara en el espacio de nombres global, mientras que se define en el espacio de nombres X.

    – bert-jan

    21 de noviembre de 2011 a las 11:27

avatar de usuario
bert-jan

El Foo::TheFunc() no está en el espacio de nombres correcto en el caso VS. Use ‘void X::Foo::TheFunc() {}’ para implementar la función en el espacio de nombres correcto (X).

  • No creo que compile, pero no porque haya una diferencia, sino porque hay un extraviado. { 😉

    – Michael Krelin – hacker

    21 de noviembre de 2011 a las 11:24

  • La diferencia es que Foo::TheFunc() se declara en el espacio de nombres global, mientras que se define en el espacio de nombres X.

    – bert-jan

    21 de noviembre de 2011 a las 11:27

avatar de usuario
alextheo

En caso de que envuelva solo el contenido .h, debe escribir usando el espacio de nombres … en el archivo cpp; de lo contrario, cada vez que trabaje en el espacio de nombres válido. Normalmente, envuelve archivos .cpp y .h; de lo contrario, corre el riesgo de usar objetos de otro espacio de nombres, lo que puede generar muchos problemas.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad