Question

Dans mon exemple ci-dessous, pourquoi dois-je saisir le nom complet de la fonction libre dans le cpp pour éviter les erreurs de l'éditeur de liens et pourquoi il travaille pour la fonction de classe sans? Pouvez-vous expliquer la différence?

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

Merci pour votre temps et aide.

Était-ce utile?

La solution

int FreeFunction(void);  

est juste une déclaration alors que le ci-dessous est une définition.

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

Si vous voulez fournir definition for an already declared entity in a namespace (par exemple dans un espace de noms enfermant), il doit être le nom complet.

EDIT2:

Voici quelque chose qui vous donnerait un peu plus de clarté. Remarque aucune directive à l'aide de ce code.

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

    class CTest;              // declare
} 

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

int main(){}

EDIT 3: Déclaration vs Définition (C ++ 0x) $ 3.1 / 2

  

Une déclaration est une définition à moins   il déclare une fonction sans   spécifiant le corps de la fonction   (8.4) , il contient les extern   spécificateur (7.1.1) ou   liaison-specification25 (7.5) et   ni un initialiseur ni   fonction corps, il déclare statique   membre des données dans une définition de classe   (9.4), il est un nom de classe   déclaration (9.1) , il est un   ENUM-déclaration opaque (7.2), ou   est une déclaration typedef (7.1.3), un   en utilisant déclaration (7.3.3), un   static_assert-déclaration (Article 7),   un attribut de déclaration (Article 7),   une déclaration vide (article 7), ou un   à l'aide-directive (7.3.4).

Autres conseils

Alors que FreeFunction résoudra à Test::FreeFunction si vous référence à ou appelez après avoir fourni la ligne de using namespace Test;, pour autant que définir la fonction va, le compilateur n'a aucun moyen savoir si vous définissez un entièrement nouvelle fonction FreeFunction en dehors de tout espace de noms, ou si vous définissez l'Test::FreeFunction déjà déclaré. Les paramètres par défaut du compilateur à penser que vous définissez une toute nouvelle fonction.

Pour CTest::CTest, cependant, vous êtes déjà se référant à la Test::CTest de classe, et comme il n'y a pas CTest classe ou espace de noms en dehors de l'espace de noms Test, eh bien, la référence à CTest::anything est sans ambiguïté. Donc, il sait que le constructeur et les définitions destructor se réfèrent à la classe dans l'espace de noms CTest.

Je pense qu'il est un petit prix à payer pour avoir à écrire Test::FreeFunction.

Hope this helps!

Si vous ne vous qualifiez pas à la définition mainlibre, le compilateur ne sait pas pour anthères sûr de vouloir assurer la mise en œuvre pour le test :: mainlibre ou pour une mainlibre séparée précédemment avant déclarée dans l'espace de noms en cours.

Par contre, il n'y a qu'une seule façon de résoudre le nom CTest - comme la définition de classe de l'espace de noms de test. Ainsi, il n'y a pas besoin de se qualifier pleinement.

Cependant, si la résolution du nom CTest est ambigu (dire qu'il ya une autre classe CTest dans l'espace de noms en cours ainsi), vous devrez qualifier complètement les déclarations de méthode.

Lors de la mise en œuvre d'une fonction, il est généralement préférable, je trouve, d'ouvrir l'espace de noms. Rappelez-vous que vous pouvez les rouvrir ...

// in Test.cpp
namespace Test
{
   int FreeFunction()
   {
       return 0;
   }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top