Quelle est la meilleure pratique lors de la programmation d'une fonction membre?

StackOverflow https://stackoverflow.com/questions/165474

  •  03-07-2019
  •  | 
  •  

Question

J'ai vu des fonctions membres être programmées à l'intérieur de la classe à laquelle elles appartiennent et à l'extérieur de la classe avec un prototype de fonction à l'intérieur de la classe. Je n’ai jamais programmé qu’en utilisant la première méthode, mais je me demandais s’il est préférable d’utiliser l’autre ou une préférence personnelle?

Était-ce utile?

La solution

En supposant que vous parliez de C ++, il est toujours préférable de définir les fonctions en dehors de la classe, car si vous les mettez dans la classe, le compilateur peut essayer de le mettre en ligne, ce qui n'est pas toujours souhaitable:

  1. Augmentation de la taille du code (chaque fichier objet contenant cet en-tête peut se retrouver avec une copie de la fonction dans son code).
  2. Rompre la compatibilité binaire lorsque la définition de la fonction change.

Même avec les fonctions inline, il est généralement préférable de placer les définitions en dehors de la classe pour améliorer la lisibilité de l'interface publique de la classe, à moins que la fonction ne soit un accesseur trivial ou un autre type à une ligne.

Autres conseils

Pour C ++, l'insertion de définitions de méthodes dans le fichier d'en-tête signifie que tout ce qui inclut un en-tête donné doit être recompilé lorsque celui-ci change - même s'il ne s'agit que d'un détail d'implémentation.

Le fait de déplacer les définitions hors de l’en-tête signifie que les fichiers incluant l’en-tête ne devront être recompilés que lorsque l’en-tête lui-même sera modifié (fonctions ajoutées / supprimées ou déclarations modifiées). Cela peut avoir un impact important sur les temps de compilation des projets complexes.

Les deux techniques présentent des avantages.

Si vous ne placez que des prototypes dans la définition de classe, il sera plus facile pour quelqu'un qui utilise votre classe de voir quelles méthodes sont disponibles. Ils ne sont pas distraits par les détails de la mise en œuvre.

Le fait de placer le code directement dans la définition de la classe simplifie l'utilisation de la classe. Il vous suffit d'inclure # un en-tête. Ceci est particulièrement utile (nécessaire) avec les classes basées sur des modèles.

En supposant que le langage soit C ++:

En fin de compte, c’est la préférence personnelle. La classe est globalement plus courte et plus directe, surtout pour les

int getFoo() const { return _foo; }

type de fonction. En dehors de la classe, vous pouvez supprimer le "fouillis". à partir de la définition de classe.

J'ai vu les deux en cours d'utilisation ...

Bien sûr, les fonctions non en ligne sont toujours en dehors de la classe.

Il est également courant de mélanger les deux styles lors de la définition d’une classe. Pour les méthodes simples comprenant 1 ou 2 lignes, il est courant et commode de définir le corps de la méthode dans la définition de classe. Pour des méthodes plus longues, il est préférable de les définir en externe. Vous aurez des définitions de classes plus lisibles sans les encombrer avec le corps de la méthode.

Il est avantageux de masquer la mise en oeuvre d'une méthode, car l'utilisateur de la classe ne sera pas distrait par la mise en œuvre réelle, ni ne formulera d'hypothèses sur la mise en œuvre susceptibles de changer à un moment ultérieur.

Je suppose que vous parlez de C ++.

Avoir une interface agréable et propre est certainement une bonne idée. Avoir un fichier d'implémentation séparé aide à garder votre interface propre.

Cela réduit également le temps de compilation, en particulier si vous utilisez un pointeur opaque .

Si vous implémentez la fonction dans la classe, vous ne pouvez pas # inclure la classe dans plusieurs fichiers .cpp, sinon l'éditeur de liens se plaindre de plusieurs définitions de la fonction.

Ainsi, la pratique habituelle est d'avoir la définition de la classe dans un fichier .h et l'implémentation des membres dans un fichier .cpp (généralement avec le même nom).

Encore une fois, en assimilant le C ++, je limite généralement cela à des espaces réservés sur des fonctions virtuelles, par exemple.

virtual int MyFunc() {}  // Does nothing in base class, override if needed

N'importe quoi d'autre, et le point d'Andrew Medico intervient trop facilement et fait mal aux temps de compilation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top