Pregunta

En mi ejemplo a continuación, ¿por qué tengo que calificar totalmente el nombre de la función libre en el CPP a errores de enlace evitar y por qué funciona para la función de la clase sin? ¿Puede explicar la diferencia?

ctest.h:

namespace Test
{
    int FreeFunction();

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

ctest.cpp:

#include "ctest.h"

using namespace Test;

// int FreeFunction()     -> undefined reference error
int Test::FreeFunction()  -> works just fine
{
    return 0;
}

CTest::CTest()                -> no need to fully qualify name, i.e. Test::CTest
{}

CTest::~CTest()
{}

Gracias por su tiempo y ayuda.

¿Fue útil?

Solución

int FreeFunction(void);  

es sólo una declaración mientras que el 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 que encierra), tiene que ser el nombre completo.

Edit2:

Aquí hay algo que le daría un poco más de claridad. Tenga en cuenta sin el uso de 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(){}

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

  

Una declaración es una definición a menos   se declara una función sin   especificando el cuerpo de la función   (8,4) , contiene la extern   especificador (7.1.1) o una   ligamiento specification25 (7.5) y   ni un inicializador, ni una   la función del cuerpo, se declara una estática   miembro de datos en una definición de clase   (9.4), es un nombre de clase   declaración (9.1) , que es una   opaco-enum-declaración (7.2), o   es una declaración typedef (7.1.3), una   usando-declaración (7.3.3), una   static_assert-declaración (Cláusula 7),   un atributo de declaración (Cláusula 7),   Un vacío-declaración (Cláusula 7), o una   usando-directiva (7.3.4).

Otros consejos

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

Para CTest::CTest, sin embargo, ya se encuentra refiriéndose a Test::CTest la clase, y ya que no hay clase o espacio de nombres CTest fuera del espacio de nombres Test, así, la referencia a CTest::anything no es ambigua. Por lo tanto, sabe que las definiciones constructor y el destructor se refieren a la clase CTest en espacio de nombres.

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

Espero que esto ayude!

Si usted no califica FreeFunction definición, el compilador no sabe a ciencia cierta anteras desea proporcionar aplicación para la ya declarada hacia adelante-Test :: FreeFunction o para un FreeFunction separada en el espacio de nombres actual.

Por otro lado, sólo hay una manera de resolver el nombre CTest - como la definición de clase desde el espacio de nombres de prueba. Por lo tanto, no hay necesidad de calificar completamente.

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

Cuando se implementa una función normalmente es preferible, encuentro, para abrir el espacio de nombres. Recuerde que usted puede volver a abrir ...

// in Test.cpp
namespace Test
{
   int FreeFunction()
   {
       return 0;
   }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top