776 votes

*.h ou *.hpp pour vos définitions de classe

J'ai toujours utilisé un fichier *.h pour mes définitions de classe, mais après avoir lu du code de bibliothèque boost, j'ai réalisé qu'ils utilisent tous *.hpp. J'ai toujours eu une aversion pour cette extension de fichier, je pense principalement parce que je n'y suis pas habitué.

Quels sont les avantages et les inconvénients d'utiliser *.hpp par rapport à *.h ?

2 votes

Pendant ce temps, il y a Les directives de base de C++ qui recommandent de manière non ambiguë *.h

3 votes

@Christophe Je ne dirais pas que la norme "de manière non équivoque" recommande *.h. Ils laissent la porte ouverte à la convention du projet : SF.1: Utilisez un suffixe .cpp pour les fichiers de code et .h pour les fichiers d'interface si votre projet ne suit pas déjà une autre convention

742voto

David Holm Points 6165

Voici quelques raisons pour lesquelles il est préférable d'avoir des noms différents pour les en-têtes C par rapport aux en-têtes C++ :

  • Formatage automatique du code, vous pouvez avoir des directives différentes pour le formatage du code C et C++. Si les en-têtes sont séparés par extension, vous pouvez configurer votre éditeur pour appliquer automatiquement le formatage approprié
  • Nommage, j'ai travaillé sur des projets où il y avait des bibliothèques écrites en C et des wrappers implémentés en C++. Comme les en-têtes avaient généralement des noms similaires, par exemple Feature.h vs Feature.hpp, il était facile de les distinguer.
  • Inclusion, peut-être que votre projet dispose de versions plus appropriées écrites en C++ mais que vous utilisez la version C (voir le point précédent). Si les en-têtes sont nommés d'après le langage dans lequel ils sont implémentés, vous pouvez facilement repérer tous les en-têtes C et vérifier s'il existe des versions en C++.

N'oubliez pas, C n'est pas C++ et il peut être très dangereux de mélanger les deux sauf si vous savez ce que vous faites. Nommage de vos sources de manière appropriée vous aide à distinguer les langages.

0 votes

Sur voté pour le dernier paragraphe!

0 votes

Pour clarifier, dangereux ne signifie pas nuisible pour vous, pour les autres ou pour votre PC. Cela signifie simplement que cela peut casser votre programme. Un abus courant du mot dans le monde du développement.

344voto

paercebal Points 38526

J'utilise .hpp car je veux que l'utilisateur différencie les en-têtes de C++ des en-têtes de C.

Cela peut être important lorsque votre projet utilise à la fois des modules C et C++ : Comme quelqu'un l'a expliqué avant moi, vous devez le faire très soigneusement, et cela commence par le "contrat" que vous offrez grâce à l'extension

.hpp : En-têtes C++

(Ou .hxx, ou .hh, ou autre)

Cet en-tête est exclusivement pour C++.

Si vous êtes dans un module C, ne cherchez même pas à l'inclure. Vous n'aimerez pas cela, car aucun effort n'est fait pour le rendre compatible avec le C (trop de choses seraient perdues, comme la surcharge de fonctions, les espaces de noms, etc.)

.h : En-têtes C/C++ compatibles ou en-têtes C purs

Cet en-tête peut être inclus par à la fois par un code source C et un code source C++, directement ou indirectement.

Il peut être inclus directement, en étant protégé par le macro __cplusplus :

  • Ce qui signifie que, du point de vue du C++, le code compatible avec le C sera défini comme extern "C".
  • Du point de vue du C, tout le code en C sera clairement visible, mais le code en C++ sera caché (car il ne compilera pas dans un compilateur C).

Par exemple:

#ifndef MY_HEADER_H
#define MY_HEADER_H

   #ifdef __cplusplus
      extern "C"
      {
   #endif

   void myCFunction() ;

   #ifdef __cplusplus
      } // extern "C"
   #endif

#endif // MY_HEADER_H

Ou il pourrait être inclus indirectement par l'en-tête correspondant .hpp en l'encadrant avec la déclaration extern "C".

Par exemple:

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP

extern "C"
{
#include "my_header.h"
}

#endif // MY_HEADER_HPP

et :

#ifndef MY_HEADER_H
#define MY_HEADER_H

void myCFunction() ;

#endif // MY_HEADER_H

12 votes

C'est assez inhabituel dans de nombreux projets C++. Les fichiers .h sont utilisés pour des choses très peu c-like.

22 votes

@einpoklum : Bien sûr. Mais j'essaie d'éviter le comportement "Monkey See Monkey Do". Dans le cas actuel, les deux extensions (et d'autres) sont disponibles, donc j'essaie de les rendre vraiment utiles. Avoir ce contrat avec du code partagé avec des clients est très utile : Tout le monde (c'est-à-dire des centaines de développeurs) sait que les fichiers ".H" doivent être utilisés par des clients utilisant un compilateur C, donc il n'y a aucune confusion sur ce qui peut y figurer ou non. Et tout le monde (y compris les clients) sait que les fichiers ".HPP" ne tenteront jamais d'être compatibles avec le C. Tout le monde y gagne.

6 votes

@paercebal, donc tu suggères .H au lieu de .h, et .HPP plutôt que .hpp?

73voto

Perculator Points 279

J'ai toujours considéré l'en-tête .hpp comme une sorte de mot-valise des fichiers .h et .cpp... un en-tête qui contient également des détails d'implémentation.

En général, lorsque j'ai vu (et utilisé) .hpp comme extension, il n'y a pas de fichier .cpp correspondant. Comme d'autres l'ont dit, ce n'est pas une règle stricte, c'est simplement la façon dont j'ai tendance à utiliser les fichiers .hpp.

53voto

Burkhard Points 6734

Peu importe l'extension que vous utilisez. Les deux sont OK.

J'utilise *.h pour le langage C et *.hpp pour le langage C++.

50voto

ProgramCpp Points 14

MODIFIER [Suggestion ajoutée par Dan Nissenbaum]:

Par une convention, les fichiers .hpp sont utilisés lorsque les prototypes sont définis dans l'en-tête lui-même. De telles définitions dans les en-têtes sont utiles en cas de modèles, puisque le compilateur génère le code pour chaque type uniquement lors de l'instanciation du modèle. Par conséquent, si elles ne sont pas définies dans les fichiers d'en-tête, leurs définitions ne seront pas résolues au moment du lien à partir d'autres unités de compilation. Si votre projet est un projet uniquement en C++ qui utilise largement des modèles, cette convention sera utile.

Certaines bibliothèques de modèles qui adhèrent à cette convention fournissent des en-têtes avec des extensions .hpp pour indiquer qu'ils n'ont pas de fichiers .cpp correspondants.

Une autre convention consiste à utiliser .h pour les en-têtes C et .hpp pour le C++; un bon exemple serait la bibliothèque boost.

Citation de la FAQ de Boost,

Les extensions de fichier communiquent le "type" du fichier, à la fois aux humains et aux programmes informatiques. L'extension '.h' est utilisée pour les fichiers d'en-tête C, ce qui communique donc une information erronée sur les fichiers d'en-tête C++. L'absence d'extension ne communique rien et oblige l'inspection du contenu du fichier pour déterminer le type. L'utilisation de '.hpp' identifie de manière non équivoque qu'il s'agit d'un fichier d'en-tête C++, et fonctionne bien en pratique. (Rainer Deyke)

0 votes

Aucune de ces affirmations n'est vraie, cela ne fait aucune différence que le fichier soit .h ou .hpp en ce qui concerne la génération de code ou le lien.

0 votes

N'est-ce pas simplement une question de convention? La bibliothèque std de C++ fournit tous ses en-têtes sans aucune extension. l'utilisation de ".hpp" indique simplement que les prototypes sont définis dans le même fichier et qu'il n'y aura pas de fichier .cpp correspondant.

19 votes

Cette réponse est utile, je pense, à l'exception qu'elle manque une phrase très simple, mais importante : "par convention, et non par les règles du langage" (quelque part).

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