Pregunta

Yo vengo de una Java de fondo, donde los paquetes se usan, no los espacios de nombres.Estoy acostumbrada a poner las clases que trabajan juntos para formar un objeto completo dentro de los paquetes, y luego usarlos más tarde a partir de ese paquete.Pero ahora estoy trabajando en C++.

¿Cómo utilizar espacios de nombres en C++?Crear un espacio de nombres único para toda la aplicación, o crear espacios de nombres para los componentes principales?Si es así, ¿cómo se puede crear objetos a partir de clases en otros espacios de nombres?

¿Fue útil?

Solución

Los espacios de nombres son los paquetes esencialmente.Pueden ser utilizados como este:

namespace MyNamespace
{
  class MyClass
  {
  };
}

A continuación, en el código:

MyNamespace::MyClass* pClass = new MyNamespace::MyClass();

Espero que ayude.

O, si usted desea usar siempre un espacio de nombres específico, usted puede hacer esto:

using namespace MyNamespace;

MyClass* pClass = new MyClass();

Editar: A raíz de lo que bernhardrusch ha dicho, tiendo a no utilizar el "using namespace x" de la sintaxis, no me suele especificar explícitamente el espacio de nombres al crear instancias de mis objetos (es decir,el primer ejemplo que se me mostró).

Y como lo pediste a continuación, se puede utilizar como número de espacios de nombres, como te gusta.

Otros consejos

Para evitar decir todo lo que Mark Ingram ya dijo un poco la punta para el uso de espacios de nombres:

Evitar el "uso de espacio de nombres" de la directiva en los archivos de encabezado - de esta forma se abre el espacio de nombres para todas las partes del programa que importar este archivo de encabezado.En la aplicación los archivos (*.cpp) esto normalmente no es gran problema - aunque yo prefiero usar el "uso de espacio de nombres" directiva sobre el nivel de función.

Creo que los espacios de nombres que se usan generalmente para evitar conflictos de nombres - no necesariamente para organizar su estructura de código.Me gustaría organizar los programas de C++ principalmente con archivos de encabezado / la estructura de archivos.

A veces los espacios de nombres se utilizan en grandes proyectos de C++ para ocultar los detalles de implementación.

Nota adicional para el uso de la directiva:Algunas personas prefieren utilizar el "uso" sólo para elementos individuales:

using std::cout;  
using std::endl;

Vincent Robert es el derecho en su comentario ¿Cómo utilizar correctamente los espacios de nombres en C++?.

El uso de espacio de nombres

Los espacios de nombres se utilizan, al menos, para ayudar a evitar la colisión de nombres.En Java, esto es forzada a través de la "org.dominio de idioma (porque se supone que uno no uso otra cosa que su propio nombre de dominio).

En C++, usted podría dar un espacio de nombres para todo el código en el módulo.Por ejemplo, para un módulo de MyModule.dll usted podría dar su código en el espacio de nombres MyModule.Yo he visto en otros lugares a alguien con Miempresa::Miproyecto::MyModule.Supongo que esto es una exageración, pero a pesar de todo, parece correcto para mí.

El uso de "uso"

El uso debe ser utilizado con mucho cuidado, ya que efectivamente la importación de uno (o todos) los símbolos de un espacio de nombres en el espacio de nombres actual.

Este es el mal de hacerlo en un archivo de cabecera porque el encabezado va a contaminar cada fuente, incluyendo (que me recuerda a la de macros...), e incluso en un archivo de código fuente, estilo malo fuera del ámbito de una función porque va a importar en el ámbito global de los símbolos del espacio de nombres.

La forma más segura de utilizar el "uso" es la importación de seleccionar los símbolos:

void doSomething()
{
   using std::string ; // string is now "imported", at least,
                       // until the end of the function
   string a("Hello World!") ;
   std::cout << a << std::endl ;
}

void doSomethingElse()
{
   using namespace std ; // everything from std is now "imported", at least,
                       // until the end of the function
   string a("Hello World!") ;
   cout << a << endl ;
}

Usted verá un montón de "using namespace std ;" en el tutorial o ejemplo de los códigos.La razón es reducir el número de símbolos para hacer la lectura más fácil, ya que no es una buena idea.

"using namespace std ;" es desalentado por Scott Meyers (no recuerdo exactamente en qué libro, pero la puedo encontrar, si es necesario).

Espacio De Nombres De La Composición

Los espacios de nombres son más que paquetes.Otro ejemplo puede encontrarse en Bjarne Stroustrup "El Lenguaje de Programación C++".

En la "Edición Especial", en 8.2.8 Espacio De Nombres De La Composición, él describe cómo se pueden fusionar dos espacios de nombres AAA y BBB en otra que se llama CCC.Por lo tanto CCC se convierte en un alias para ambos AAA y BBB:

namespace AAA
{
   void doSomething() ;
}

namespace BBB
{
   void doSomethingElse() ;
}

namespace CCC
{
   using namespace AAA ;
   using namespace BBB ;
}

void doSomethingAgain()
{
   CCC::doSomething() ;
   CCC::doSomethingElse() ;
}

Usted puede incluso importar símbolos de diferentes espacios de nombres, para construir su propio espacio de nombres personalizado de la interfaz.Todavía tengo que encontrar un uso práctico de este, pero, en teoría, es genial.

Yo no veo ninguna mención de él en las otras respuestas, así que aquí están mis 2 centavos de dólar Canadiense:

En "usar el espacio de nombres" tema, un útil declaración es el espacio de nombres de alias, que permite "cambiar el nombre de" un espacio de nombres, normalmente para darle un nombre más corto.Por ejemplo, en lugar de:

Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally::TheClassName foo;
Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally::AnotherClassName bar;

se puede escribir:

namespace Shorter = Some::Impossibly::Annoyingly::Long:Name::For::Namespace::Finally;
Shorter::TheClassName foo;
Shorter::AnotherClassName bar;

No escuche a todas las personas diciendo que los espacios de nombres son sólo el nombre de los espacios.

Son importantes debido a que son considerados por el compilador para aplicar la interfaz principio.Básicamente, se puede explicar mediante un ejemplo:

namespace ns {

class A
{
};

void print(A a)
{
}

}

Si desea imprimir Un objeto, el código sería este:

ns::A a;
print(a);

Tenga en cuenta que nosotros no menciona explícitamente el espacio de nombres cuando se llama a la función.Esta es la interfaz de principio:C++ considerar una función que recibe un tipo de un argumento como parte de la interfaz de ese tipo, así que no hay necesidad de especificar el espacio de nombres debido a que el parámetro ya implícita en el espacio de nombres.

Ahora, ¿por qué este principio es importante?Imagino que la clase de Un autor no proporciona la función print() de esta clase.Usted tendrá que proporcionar uno a sí mismo.Como eres un buen programador, va a definir esta función en su propio espacio de nombres, o tal vez en el espacio de nombres global.

namespace ns {

class A
{
};

}

void print(A a)
{
}

Y su código puede comenzar a llamar a la impresión(a) función de dondequiera que usted desee.Ahora imaginar que años más tarde, el autor decide proporcionar la función print (), mejor que la suya, porque él conoce las interioridades de su clase y puede hacer una mejor versión que la tuya.

Luego C++ autores decidieron que su versión de la función print() debe ser utilizado en lugar de la establecida en otro espacio de nombres, a respetar la interfaz principio.Y que esta "actualización" de la función print() debería ser tan fácil como sea posible, lo que significa que usted no tendrá que cambiar cada vez que se llame a la función print ().Es por eso que "las funciones de interfaz" (función en el mismo espacio de nombres de la clase) puede ser llamado sin especificar el espacio de nombres en C++.

Y es por eso que usted debe considerar un C++ espacio de nombres como una "interfaz" cuando se usa uno y tener en cuenta la interfaz de principio.

Si desea una mejor explicación de este comportamiento, puede consultar el libro Excepcional C++ de Herb Sutter

Grandes proyectos de C++ he visto prácticamente no se utiliza más de un espacio de nombres (por ejemplo,impulso de la biblioteca).

En realidad aumentar los usos de toneladas de espacios de nombres, normalmente cada parte de boost tiene su propio espacio de nombres para el funcionamiento interno y, a continuación, puede poner sólo la interfaz pública en el nivel superior del espacio de nombres de impulso.

Personalmente creo que la más grande es una base de código se convierte en el más importante de los espacios de nombres se convierten, incluso dentro de una sola aplicación (o biblioteca).En el trabajo que tenemos que poner cada uno de los módulos de nuestra aplicación en su propio espacio de nombres.

Otro uso (sin juego de palabras) de los espacios de nombres que uso mucho es el anónimo de espacio de nombres:

namespace {
  const int CONSTANT = 42;
}

Esta es básicamente la misma:

static const int CONSTANT = 42;

El uso de un anónimo espacio de nombres (en lugar de estático) es, sin embargo, la forma recomendada para el código y los datos a ser visible sólo dentro de la actual unidad de compilación en C++.

También, tenga en cuenta que puede agregar a un espacio de nombres.Esto es más claro con un ejemplo, lo que quiero decir es que usted puede tener:

namespace MyNamespace
{
    double square(double x) { return x * x; }
}

en un archivo square.h, y

namespace MyNamespace
{
    double cube(double x) { return x * x * x; }
}

en un archivo cube.h.Esto define un espacio de nombres único MyNamespace (es decir, se puede definir un espacio de nombres único a través de múltiples archivos).

En Java:

package somepackage;
class SomeClass {}

En C++:

namespace somenamespace {
    class SomeClass {}
}

Y ellos, utilizando Java:

import somepackage;

Y C++:

using namespace somenamespace;

También, los nombres completos son "somepackge.SomeClass" para Java y "somenamespace::SomeClass" para C++.Mediante estos convenios, se puede organizar como usted está acostumbrado en Java, incluyendo la realización de la coincidencia de los nombres de carpeta para los espacios de nombres.La carpeta->paquete y el archivo->requisitos de la clase no son de allí, sin embargo, así que usted puede poner el nombre a las carpetas y las clases de forma independiente fuera de los paquetes y espacios de nombres.

Puede contener también "uso de espacio de nombres ..." dentro de una función, por ejemplo:

void test(const std::string& s) {
    using namespace std;
    cout << s;
}

@marius

Sí, puede utilizar varios espacios de nombres en un tiempo, por ejemplo:

using namespace boost;   
using namespace std;  

shared_ptr<int> p(new int(1));   // shared_ptr belongs to boost   
cout << "cout belongs to std::" << endl;   // cout and endl are in std

[Feb.2014 -- (¿Ha sido realmente que largo?):Este ejemplo en particular es ahora ambiguo, ya que Joey se señala a continuación.Impulsar y std::ahora cada uno tiene un shared_ptr.]

En general, estoy crear un espacio de nombres para un cuerpo de código si yo creo que no podría ser, posiblemente, la función o el nombre del tipo de conflictos con otras bibliotecas.También ayuda a código de marca, ala boost:: .

Yo prefiero usar un nivel superior del espacio de nombres de la aplicación y sub espacios de nombres para los componentes.

La forma en que usted puede utilizar las clases de otros espacios de nombres es, sorprendentemente, muy similar a la forma en java.Usted puede utilizar el "uso de espacio de NOMBRES", que es similar a una "importación" PAQUETE de instrucción, por ejemplo,el uso de las ets.O especificar el paquete como prefijo de la clase separados por "::", por ejemplo,std::string.Esto es similar a "de java.lang.Cadena" en Java.

Tenga en cuenta que un espacio de nombres en C++ en realidad es sólo un espacio de nombre.Ellos no proporcionan ninguna de la encapsulación de los paquetes hacerlo en Java, por lo que probablemente no va a hacer uso de ellos.

He usado C++ espacios de nombres de la misma manera en que lo hago en C#, Perl, etc.Es sólo una semántica de la separación de los símbolos entre los de la biblioteca estándar de cosas, de terceros cosas, y mi propio código.Me gustaría poner mi propia app en un espacio de nombres, a continuación, una biblioteca reutilizable componente en otro espacio de nombres para la separación.

Otra diferencia entre java y C++, es que en C++, la jerarquía del espacio de nombres no necesita de mach a la disposición de archivos.Por lo que tienden a poner toda una biblioteca reutilizable en un único espacio de nombres, y de los subsistemas dentro de la biblioteca en subdirectorios:

#include "lib/module1.h"
#include "lib/module2.h"

lib::class1 *v = new lib::class1();

Sólo quiero poner de los subsistemas en los espacios de nombres anidados si existía la posibilidad de un conflicto de nombres.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top