espacios de nombres, clases y funciones gratuitas - ¿cuándo necesita nombres completos
-
28-09-2019 - |
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.
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;
}
}