49 votes

Les méthodes de classe C++ inlining provoquent une référence indéfinie

J'obtiens une erreur de compilation lorsque j'essaie de mettre en ligne une méthode d'une de mes classes. Cela fonctionne lorsque je supprime le mot-clé "inline".

Voici un exemple simplifié :

main.cpp :

#include "my_class.h"

int main() {
  MyClass c;
  c.TestMethod();

  return 0;
}

ma_classe.h :

class MyClass {
 public:
  void TestMethod();
};

ma_classe.cpp :

#include "my_class.h"

inline void MyClass::TestMethod() {
}

J'essaie de compiler avec :

g++ main.cpp my_class.cpp

Je reçois l'erreur :

main.cpp:(.text+0xd): undefined reference to `MyClass::TestMethod()'

Tout va bien si j'enlève le "inline". Quelle est la cause de ce problème ? (et comment dois-je mettre en ligne les méthodes des classes ? Est-ce possible ?)

Merci.

43voto

casablanca Points 41814

Le corps d'une fonction inline doit se trouver dans l'en-tête pour que le compilateur puisse la substituer là où c'est nécessaire. Voir ceci : Comment dire au compilateur de mettre une fonction membre en ligne ?

17voto

Steve Jessop Points 166970

7.1.2/4 de la norme :

Une fonction en ligne doit être définie dans chaque unité de traduction dans laquelle elle est utilisée...

Vous utilisez TestMethod dans main.cpp, mais il n'y est pas défini.

... Si une fonction avec un lien externe est déclarée en ligne dans une traduction elle doit être déclarée inline dans toutes les unités de traduction dans lesquelles elle dans lesquelles elle apparaît ; aucun diagnostic n'est requis.

Vous définissez (et donc déclarez également) TestMethod en ligne dans my_class.cpp, mais pas dans main.cpp.

Dans ce cas, la solution consiste à déplacer la définition de la fonction vers le fichier d'en-tête, de la manière suivante :

class MyClass {
 public:
  void TestMethod() {}
};

ou comme ça :

class MyClass {
 public:
  inline void TestMethod();
};

inline void MyClass::TestMethod() {}

3voto

wheaties Points 20917

Vous l'avez défini comme non inline dans le fichier d'en-tête, alors que dans le fichier cpp vous essayez de le définir comme inline. Il s'agit d'une définition contradictoire et il ne sera pas en mesure de trouver l'une de l'autre. Votre en-tête est l'endroit où vous devez placer le mot-clé inline.

Cependant, je supprimerais le mot-clé inline car il s'agit plutôt d'une suggestion au compilateur. Vous n'en avez vraiment besoin que lorsqu'il y a une fonction flottante dans l'en-tête et que vous ne voulez pas que de multiples définitions apparaissent dans votre base de code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X