Définir la méthode statique dans le fichier source avec une déclaration dans le fichier d'en-tête en C ++

142

J'ai un peu de mal à travailler avec des méthodes statiques en C ++

Exemple .h:

class IC_Utility {
public:
    IC_Utility();
    ~IC_Utility();

    std::string CP_PStringToString( const unsigned char *outString );
    void CP_StringToPString( std::string& inString, unsigned char *outString, short inMaxLength );
    static void CP_StringToPString( std::string& inString, unsigned char *outString);
    void CP_StringToPString( FxString& inString, FxUChar *outString);

};

Exemple .cpp:

static void IC_Utility::CP_StringToPString(std::string& inString, unsigned char *outString)
{
    short       length = inString.length();

   if( outString != NULL )
    {
        if( length >= 1 )
            CPLAT::CP_Utility::CP_CopyMemory( inString.c_str(), &outString[ 1 ], length );

            outString[ 0 ] = length;
    }
}

Je voulais passer un appel comme:

IC_Utility::CP_StringToPString(directoryNameString, directoryName );

Mais j'obtiens une erreur:

error: cannot declare member function 'static void IC_Utility::CP_StringToPString(std::string&, unsigned char*)' to have static linkage

Je ne comprends pas pourquoi je ne peux pas faire ça. Quelqu'un peut-il m'aider à comprendre pourquoi et comment réaliser ce que je veux?

ABV
la source
2
Tout d'abord, vous devez supprimer le staticmot - clé dans le fichier .cpp. C ++ ne le permet pas.
Fezvez
10
@Fezvez: Sinon, remplacez-le par /* static */. J'aime avoir les mêmes modificateurs et arguments par défaut dans les fichiers .h et .cpp.
David Thornley
2
TL; DR: Gardez staticdans le fichier d'en-tête .h, cela signifie "attaché à la classe, pas à un objet", supprimez-le staticdans le .cppfichier, cela a une signification différente que vous ne voulez pas ici.
Stéphane Gourichon

Réponses:

228

Supprimer le staticmot-clé dans la définition de méthode. Gardez-le juste dans votre définition de classe.

staticLe mot clé placé dans le fichier .cpp signifie qu'une certaine fonction a un lien statique, ie. il n'est accessible qu'à partir d'autres fonctions du même fichier.

x13n
la source
1
Ah, compris, staticla définition de la méthode signifierait que seules les autres méthodes de cette classe peuvent accéder à cette méthode statique, aucune autre méthode en dehors de cette classe.
ABV
14
Pas d'autres méthodes de classe, mais d'autres fonctions dans le fichier .cpp. Vous ne devriez de toute façon pas faire cela en C ++. Si vous souhaitez qu'une fonction C ++ ait une liaison interne, vous devez envisager de la placer dans un espace de noms anonyme. L'utilisation de staticfichiers .cpp est juste pour la compatibilité descendante avec C.
x13n
1
Juste par curiosité ... Si je définis un membre de classe statique directement dans la classe (dans le fichier .h), comment pourrais-je utiliser le lien statique?
lombaire
Vous ne pouvez pas. Et cela n'a aucun sens de le faire, car la liaison du programme entraînerait l'apparition d'externes non résolus.
x13n
41

Mots clés staticet virtualne doit pas être répété dans la définition. Ils ne doivent être utilisés que dans la déclaration de classe.

Bo Persson
la source
11

Vous n'avez pas besoin d'avoir staticune définition de fonction

cpx
la source
-3

Les fonctions membres statiques doivent faire référence à des variables statiques de cette classe. Donc dans votre cas,

static void CP_StringToPString( std::string& inString, unsigned char *outString);

Étant donné que votre fonction membre CP_StringToPstringest statique, les paramètres de cette fonction, inStringet outStringdoivent être déclarées comme statiques aussi.

Les fonctions membres statiques ne font pas référence à l'objet sur lequel elles travaillent, mais les variables que vous avez déclarées se réfèrent à son objet actuel et renvoient donc une erreur.

Vous pouvez soit supprimer la statique de la fonction membre, soit ajouter de la statique tout en déclarant les paramètres que vous avez utilisés pour la fonction membre comme statiques également.

Prince Aloies
la source
2
inString et outString sont des arguments de fonction statique. Ce ne sont pas des membres de la classe. Il n'est pas nécessaire de les convertir en statique.
999k
Ce n'est pas du tout correct. Vous pouvez placer des arguments non statiques dans une fonction membre statique. Mais parmi les membres de la classe, vous ne pouvez accéder / modifier que les statiques de la fonction.
Zachary Kraus