Domanda

Nel mio esempio qui sotto, perché devo qualificare completamente il nome della funzione libera nella cpp per errori del linker evitare e perché funziona per la funzione di classe senza? Ci può spiegare la differenza?

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()
{}

Grazie per il vostro tempo e aiuto.

È stato utile?

Soluzione

int FreeFunction(void);  

è solo una dichiarazione, mentre il sotto è una definizione.

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

Se si desidera fornire definition for an already declared entity in a namespace (ad esempio in uno spazio dei nomi che racchiude), deve essere il nome completo.

EDIT2:

Qui c'è qualcosa che possa dare qualche maggiore chiarezza. Nota n direttiva using in questo codice.

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

    class CTest;              // declare
} 

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

int main(){}

EDIT 3: Dichiarazione vs definizione (C ++ 0x) $ 3,1 / 2-

  

Una dichiarazione è una definizione a meno che   dichiara una funzione senza   specificando il corpo della funzione   (8.4) , contiene l'extern   specificatore (7.1.1) o un   linkage-specification25 (7.5) e   né un inizializzatore né   funzione-corpo, dichiara statica   membro di dati in una definizione di classe   (9.4), è un nome di classe   Dichiarazione (9.1) , si tratta di un   opaco-enum dichiarazione (7.2), oppure   è una dichiarazione typedef (7.1.3), un   dichiarazione using (7.3.3), un   static_assert dichiarazione (clausola 7),   un attributo dichiarazione (clausola 7),   un vuoto dichiarazione (articolo 7), o   using-directive (7.3.4).

Altri suggerimenti

Mentre FreeFunction si risolverà per Test::FreeFunction se fa riferimento ad essa o chiamare dopo aver fornito la linea using namespace Test;, per quanto che definisce la funzione va, il compilatore non ha modo per sapere se si sta definendo un del tutto nuova funzione FreeFunction di fuori di ogni spazio dei nomi, o se si sta definendo il Test::FreeFunction già dichiarato. Le impostazioni predefinite del compilatore a pensare che si sta definendo una funzione completamente nuova.

Per CTest::CTest, tuttavia, siete già riferimento alla la classe Test::CTest, e dal momento che non c'è classe o spazio dei nomi CTest al di fuori dello spazio dei nomi Test, bene, il riferimento a CTest::anything è inequivocabile. Quindi sa che le definizioni costruttore e distruttore si riferiscono alla classe CTest in-namespace.

Credo che sia un piccolo prezzo da pagare, di dover Test::FreeFunction scrittura.

Spero che questo aiuti!

Se non si qualificano definizione FreeFunction, il compilatore non sa per certo antere si desidera fornire implementazione per il già avanti dichiarato Test :: FreeFunction o per una FreeFunction separata nello spazio dei nomi corrente.

D'altra parte, c'è solo un modo per risolvere il nome CTest - come la definizione della classe dallo spazio dei nomi di prova. Così, non c'è bisogno di qualificare pienamente.

Tuttavia, se la risoluzione dei nomi CTest è ambiguo (dicono c'è un'altra classe CTest nello spazio dei nomi corrente pure), si dovrà qualificare pienamente le dichiarazioni di metodo.

Quando si implementa una funzione di solito è preferibile, trovo, ad aprire lo spazio dei nomi. Ricorda che puoi ri-aprire ...

// in Test.cpp
namespace Test
{
   int FreeFunction()
   {
       return 0;
   }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top