Frage

In meinem Beispiel unten, warum habe ich vollständig den Namen der freien Funktion in der CPP zu vermeiden Linkerfehler zu qualifizieren und warum funktioniert es für die Klasse Funktion ohne? Können Sie den Unterschied erklären?

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

Vielen Dank für Ihre Zeit und Hilfe.

War es hilfreich?

Lösung

int FreeFunction(void);  

ist nur eine Erklärung, während die unter der Definition ist.

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

Wenn Sie bieten definition for an already declared entity in a namespace wollen (zum Beispiel in einer einschließenden Namespace), hat es voll qualifizierte Namen sein.

EDIT2:

Hier ist etwas, das Sie etwas mehr Klarheit geben würde. Hinweis kein using-Direktive in diesem Code.

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

    class CTest;              // declare
} 

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

int main(){}

EDIT 3: Erklärung vs Definition (C ++ 0x) $ 3.1 / 2-

  

Eine Erklärung ist eine Definition es sei denn,   es erklärt, eine Funktion ohne   Spezifizieren des Körpers Funktion   (8.4) , enthält es die extern   Spezifizierer (7.1.1) oder ein   gestänge specification25 (7.5) und   weder ein initializer noch ein   Funktionskörper, erklärt sie eine statische   Datenelement in einer Klassendefinition   (9.4), ist ein Klassenname   Erklärung (9.1) ist es ein   opaque-ENUM-Deklaration (7.2), oder   ist eine typedef Deklaration (7.1.3), ein   Verwendung Deklaration (7.3.3), ein   static_assert-Deklaration (Ziffer 7),   eine Attributdeklaration (Ziffer 7),   eine Leermeldung (Ziffer 7) oder eine   using-Direktive (7.3.4).

Andere Tipps

Während FreeFunction zu Test::FreeFunction lösen, wenn Sie darauf verweisen oder nennen es nach der using namespace Test; Linie bereitstellt, so weit wie definieren die Funktion geht, hat der Compiler keine Möglichkeit, zu wissen, ob Sie eine ganz neue Funktion FreeFunction außerhalb eines Namespace sind definiert, oder ob Sie die bereits erklärt Test::FreeFunction sind zu definieren. Der Compiler standardmäßig denken, dass Sie eine völlig neue Funktion sind zu definieren.

Für CTest::CTest, aber du bist schon unter die Klasse Test::CTest, und da es keine Klasse oder Namespace CTest außerhalb des Test Namespace, na ja, der Verweis auf CTest::anything eindeutig ist. So ist es weiß, dass beziehen sich die Konstruktor und Destruktor-Definitionen in der in-Namespace-Klasse CTest.

Ich denke, es ist ein kleiner Preis zu zahlen, zu schreiben Test::FreeFunction zu haben.

Hope, das hilft!

Wenn Sie nicht FreeFunction Definition qualifizieren, der Compiler nicht weiß sicher anthere Sie Implementierung für die zuvor voraus erklärt Test :: FreeFunction oder für einen separaten FreeFunction im aktuellen Namensraum zur Verfügung stellen möchten.

Auf der anderen Seite gibt es nur einen Weg, den Namen CTest zu lösen - wie die Klassendefinition aus dem Test-Namespace. Somit gibt es keine Notwendigkeit, sie vollständig zu qualifizieren.

Wenn jedoch die CTest Namensauflösung nicht eindeutig ist (sagen, es ist eine andere CTest Klasse im aktuellen Namensraum als auch), Sie haben völlig die Methode Deklarationen.

Wenn Sie eine Funktion deren Umsetzung in der Regel vorzuziehen ist, finde ich, den Namensraum zu öffnen. Denken Sie daran, Sie können wieder öffnen sie ...

// in Test.cpp
namespace Test
{
   int FreeFunction()
   {
       return 0;
   }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top