7

En mi ejemplo a continuación, ¿por qué tengo que calificar completamente el nombre de la función gratuita en cpp para evitar errores de enlazador y por qué funciona para la clase? función sin? Puedes explicar la diferencia?espacios de nombres, clases y funciones gratuitas: ¿cuándo necesita nombres completos?

ctest.h:

namespace Test 
{ 
    int FreeFunction(); 

    class CTest 
    { 
     public: 
      CTest(); 
      ~CTest(); 
    }; 
} 

ctest.cpp:

Gracias por su ayuda & tiempo.

+0

Tenga en cuenta que especificar 'void' como argumento, aunque útil en C, es inútil y se considera un estilo incorrecto en C++: http://www.parashift.com/c++ -faq-lite/newbie.html # faq-29.4 – log0

+0

@Ugo: Edité mi pregunta para eliminar esa abominación. Gracias por señalar eso. – nabulke

Respuesta

11
int FreeFunction(void); 

es solo una declaración, mientras que la siguiente es una definición.

class CTest 
{ 
    public: 
     CTest(); 
     ~CTest(); 
}; 

Si desea proporcionar definition for an already declared entity in a namespace (por ejemplo, en un espacio de nombres de cerco), que tiene que ser nombre completo.

Edit2:

Aquí es algo que le daría un poco más de claridad. Tenga en cuenta que no se usa directiva en este código.

namespace Test { 
    int FreeFunction(void); // declare 

    class CTest;    // declare 
} 

int Test::FreeFunction(){return 0;} // define 
class Test::CTest{   // define 
}; 

int main(){} 

Datos 3: Declaración vs Definición (C++ 0x) $ 3,1/2-

Una declaración es una definición menos se declara una función sin especificando el cuerpo de la función (8.4), contiene el especificador externo (7.1.1) o un especificación de enlace25 (7.5) y ni un inicializador ni un cuerpo de función , declara un miembro de datos estática en una definición de clase (9.4), es un nombre de clase declaración (9.1), es un opaco-enum-declaración (7.2), o es una declaración typedef (7,1 0.3), un usando-declaración (7.3.3), un static_assert-declaración (Cláusula 7), un atributo-declaración (Cláusula 7), un vacío-declaración (Cláusula 7), o una using- directiva (7.3.4).

+0

¿Es correcto decir que en mi ctest.h defino la clase CTest, pero solo declaro las funciones miembro de CTest? – nabulke

+0

Sí, tienes razón. Además, una función se puede definir en línea en el espacio de nombres o se puede definir en cualquiera de sus espacios de nombres con la calificación completa – Chubsdad

+0

Muy buena respuesta con ejemplos y una buena explicación. Me ayudó a entender el problema. Gracias – nabulke

1

Si usted no califica definición FreeFunction, el compilador no sabe a ciencia cierta anteras desea proporcionar implementación para el Test :: FreeFunction anteriormente indicados delante o por un FreeFunction separada en el espacio de nombres actual.

Por otro lado, solo hay una forma de resolver el nombre CTest: como la definición de clase del espacio de nombres de Prueba. Por lo tanto, no hay necesidad de calificarlo completamente.

Sin embargo, si la resolución del nombre de CTest es ambigua (digamos que hay otra clase de CTest en el espacio de nombres actual también), tendrá que calificar completamente las declaraciones de métodos.

1

Mientras FreeFunction resolverá a Test::FreeFunctionsi se refieren a ella o llama después de proporcionar la línea using namespace Test;, por lo que definir la función va, el compilador no tiene forma de saber si está definiendo un función completamente nuevaFreeFunction fuera de cualquier espacio de nombres, o si está definiendo el ya declarado Test::FreeFunction. El compilador predetermina pensar que está definiendo una función completamente nueva.

Para CTest::CTest, sin embargo, ya se están refiriendo a la clase Test::CTest, y puesto que no hay clase o espacio de nombres CTest fuera del espacio de nombres Test, así, la referencia a CTest::anything es inequívoca. Por lo tanto, sabe que las definiciones de constructor y destructor se refieren a la clase in-namespace CTest.

Creo que es un pequeño precio a pagar, tener que escribir Test::FreeFunction.

Espero que esto ayude!

0

Al implementar una función, generalmente es preferible, me parece, abrir el espacio de nombres. Recuerde que puede volver a abrirlos ...

// in Test.cpp 
namespace Test 
{ 
    int FreeFunction() 
    { 
     return 0; 
    } 
}