2010-07-07 13 views
25

No estoy seguro de qué hacer al anidar espacios de nombres y declaraciones de objetos.NameSpaces anidados en C++

Estoy portando algún código que enlaza con una biblioteca estática que tiene algunos espacios de nombres.

Ejemplo de lo que estoy hablando:

namespace ABC { 

    namespace XYZ { 

     //STUFF 
    } 
} 

En el código ¿qué hago para declarar un objeto que está en espacio de nombres XYZ?

si trato:

XYZ::ClassA myobject; 

o:

ABC::XYZ::ClassA myobject; 

o:

ABC::ClassA myobject; 

me sale

no nombra a un tipo

errores, a pesar de que ClassA definitivamente existe.

¿Qué es correcto aquí?

+3

Yo diría que - no use espacios de nombres anidados, mantenga su esquema de espacio de nombres lo más simple posible. –

+1

Lo que has intentado es obviamente correcto. ¿Tal vez escribiste mal un espacio de nombres/clase en tu código real? También puede verificar la ** mayúscula y minúscula ** (este es un error común). – ereOn

+1

Solo asegúrate de ... Sabes que declarar una nueva clase dentro de los espacios de nombre anidados es diferente a hacer referencia a un objeto declarado en una biblioteca externa desde dentro de ellos. – Jay

Respuesta

40

Depende del espacio de nombres que ya son:

Si estás en ningún espacio de nombres u otra, espacio de nombres sin relación, entonces usted tiene que especificar a la ruta entera ABC::XYZ::ClassA.

Si está en ABC puede omitir el ABC y simplemente escribir XYZ::ClassA.

Además, vale la pena mencionar que si se quiere hacer referencia a una función que no se encuentra en un espacio de nombres (o el espacio de nombres "raíz"), se puede prefijar por :::

Ejemplo:

int foo() { return 1; } 

namespace ABC 
{ 
    double foo() { return 2.0; } 

    void bar() 
    { 
    foo(); //calls the double version 
    ::foo(); //calls the int version 
    } 
} 
4

Si myobject está declarado en ese espacio de nombres y desea declararlo de nuevo (para definirlo), lo hace al ponerle un prefijo, no su tipo.

ClassA ABC::XYZ::myobject; 

Si su tipo se declara en ese espacio de nombres también, también necesita el prefijo el nombre del tipo de

ABC::XYZ::ClassA ABC::XYZ::myobject; 

Rara vez se necesita para redeclare un objeto de esa manera. A menudo, la primera declaración de un objeto es también su definición. Si quiere declarar primero el objeto, debe hacerlo en ese espacio de nombres. El siguiente declara y define "myObject"

namespace ABC { 
    namespace XYZ { 
    ClassA myobject; 
    } 
} 

Si ha definido en el objeto de este tipo, que se refieren a ella diciendo ABC::XYZ.No tiene que "declarar" ese objeto de alguna manera para usarlo localmente

void f() { 
    ABC::XYZ::myobject = someValue; 

    // you *can* however use a using-declaration 
    using ABC::XYZ::myobject; 
    myobject = someValue; 
} 
+0

"A menudo, la primera declaración de un objeto es también su definición" Esto parece estar equivocado. Si desea declarar algún objeto en un archivo de encabezado, no debe definirse allí. De lo contrario, si hay 2 archivos cpp que incluyen este encabezado, y compilaremos e intentaremos vincular estos archivos cpp, el enlazador devolverá un error sobre la definición duplicada. Si el segundo fragmento de código está a punto de estar en un encabezado, debe ser 'namespace ABC {namespace XYZ {extern ClassA myobject;}}' y luego en un archivo cpp correspondiente debe haber 'ClassA ABC :: XYZ :: myobject; '(si ClassA no está en un espacio de nombres) – Number47

+0

@ Number47 ¿por qué está mal? No dije "Todas las declaraciones de objetos son definiciones", que parece asumir que tengo. –

+0

@Johnnes No dije que "En todos los casos es incorrecto". Pero en serio. Si estamos hablando de cosas como 'namespace ABC {...}', entonces es muy probable que se trate de archivos de encabezado (¿estoy equivocado?). Pero es una mala práctica poner algo como 'ClassA myobject;' en un encabezado, ya que puede causar errores del enlazador, como señalé. Entonces, en el fragmento 3 '- Lo siento, en la publicación anterior también debería ser 3 ° - debería haber 'extern myAject de ClassA;' o debería haber una nota de que este fragmento está a punto de ser utilizado en archivos cpp, no en encabezados. De otra manera, podemos engañar a nuestros lectores. :) – Number47