it-swarm.com.de

* .h oder * .hpp für Ihre Klassendefinitionen

Ich habe immer ein *.h Datei für meine Klassendefinitionen, aber nachdem ich einige Boost-Bibliothekscodes gelesen hatte, wurde mir klar, dass sie alle *.hpp. Ich hatte immer eine Abneigung gegen diese Dateierweiterung, ich denke hauptsächlich, weil ich nicht daran gewöhnt bin.

Welche Vor- und Nachteile hat die Verwendung von *.hpp Über *.h?

493
Mark Ingram

Hier einige Gründe für die unterschiedliche Benennung von C- und C++ - Headern:

  • Bei der automatischen Code-Formatierung gelten möglicherweise andere Richtlinien für die Formatierung von C- und C++ - Code. Wenn die Überschriften durch eine Erweiterung getrennt sind, können Sie Ihren Editor so einstellen, dass die entsprechende Formatierung automatisch angewendet wird
  • Ich war an Projekten beteiligt, in denen Bibliotheken in C geschrieben und Wrapper in C++ implementiert wurden. Da die Header normalerweise ähnliche Namen hatten, d. H. Feature.h vs Feature.hpp, waren sie leicht zu unterscheiden.
  • Einbeziehung, vielleicht hat Ihr Projekt passendere Versionen, die in C++ geschrieben sind, aber Sie verwenden die C-Version (siehe oben). Wenn die Überschriften nach der Sprache benannt sind, in der sie implementiert sind, können Sie alle C-Überschriften leicht erkennen und nach C++ - Versionen suchen.

Denken Sie daran, C ist nicht C++ und es kann sehr gefährlich sein, es zu mischen und abzugleichen, wenn Sie nicht wissen, was Sie tun. Wenn Sie Ihre Quellen entsprechend benennen, können Sie die Sprachen besser voneinander unterscheiden.

473
David Holm

Ich verwende .hpp, weil der Benutzer unterscheiden soll, welche Header C++ - und welche C-Header sind.

Dies kann wichtig sein, wenn Ihr Projekt sowohl C- als auch C++ - Module verwendet: Wie jemand anderes vor mir erklärt hat, sollten Sie dies sehr sorgfältig tun, und dies beginnt mit dem "Vertrag", den Sie durch die Erweiterung anbieten

.hpp: C++ - Header

(Oder .hxx oder .hh oder was auch immer)

Dieser Header ist nur für C++.

Wenn Sie sich in einem C-Modul befinden, versuchen Sie nicht einmal, es einzuschließen. Sie werden es nicht mögen, da keine Anstrengungen unternommen werden, um es C-freundlich zu machen (es würde zu viel verloren gehen, wie Funktionsüberladung, Namespaces usw. usw.).

.h: C/C++ kompatible oder reine C-Header

Dieser Header kann direkt oder indirekt sowohl von einer C-Quelle als auch von einer C++ - Quelle eingeschlossen werden.

Es kann direkt eingebunden werden und wird durch das Makro __cplusplus Geschützt:

  • Was bedeutet, dass aus Sicht von C++ der C-kompatible Code als extern "C" Definiert wird.
  • Aus C-Sicht ist der gesamte C-Code deutlich sichtbar, der C++ - Code wird jedoch ausgeblendet (da er in einem C-Compiler nicht kompiliert werden kann).

Zum Beispiel:

#ifndef MY_HEADER_H
#define MY_HEADER_H

   #ifdef __cplusplus
      extern "C"
      {
   #endif

   void myCFunction() ;

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

#endif // MY_HEADER_H

Oder es kann indirekt durch den entsprechenden .hpp-Header eingeschlossen werden, der ihn mit der Deklaration extern "C" Umschließt.

Zum Beispiel:

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP

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

#endif // MY_HEADER_HPP

und:

#ifndef MY_HEADER_H
#define MY_HEADER_H

void myCFunction() ;

#endif // MY_HEADER_H
216
paercebal

Ich habe den .hpp - Header immer als eine Art Portmanteau von .h - und .cpp - Dateien angesehen ... ein Header, der auch Implementierungsdetails enthält.

Wenn ich .hpp Als Erweiterung gesehen (und verwendet) habe, gibt es normalerweise keine entsprechende .cpp - Datei. Wie andere gesagt haben, ist dies keine feste Regel, nur wie ich dazu neige, .hpp - Dateien zu verwenden.

46
Perculator

Es spielt keine Rolle, welche Erweiterung Sie verwenden. Beides ist in Ordnung.

Ich benutze *.h für C und *.hpp für C++.

27
Burkhard

EDIT [Vorschlag von Dan Nissenbaum hinzugefügt]:

Gemäß einer Konvention werden .hpp-Dateien verwendet, wenn die Prototypen im Header selbst definiert sind. Solche Definitionen in Headern sind bei Vorlagen nützlich, da der Compiler den Code für jeden Typ nur bei der Vorlageninstanziierung generiert. Wenn sie daher nicht in Header-Dateien definiert sind, werden ihre Definitionen zum Zeitpunkt der Verknüpfung von anderen Kompilierungseinheiten nicht aufgelöst. Wenn es sich bei Ihrem Projekt um ein reines C++ - Projekt handelt, bei dem Vorlagen häufig verwendet werden, ist diese Konvention möglicherweise hilfreich.

Bestimmte Vorlagenbibliotheken, die dieser Konvention entsprechen, bieten Kopfzeilen die Erweiterung .hpp, um anzuzeigen, dass sie keine entsprechenden .cpp-Dateien haben.

Einige andere Vorlagenbibliotheken verwenden eine andere Konvention, z. B. .h für C-Header und .hpp für C++. Ein gutes Beispiel wäre die Boost-Bibliothek.

Zitat aus Boost FAQ,

Dateierweiterungen kommunizieren den "Typ" der Datei sowohl an Menschen als auch an Computerprogramme. Die Erweiterung '.h' wird für C-Header-Dateien verwendet und kommuniziert daher das Falsche über C++ - Header-Dateien. Die Verwendung der Erweiterung no kommuniziert nichts und erzwingt die Überprüfung des Dateiinhalts, um den Typ zu bestimmen. Die Verwendung von '.hpp' identifiziert es eindeutig als C++ - Headerdatei und funktioniert in der Praxis gut. (Rainer Deyke)

21
ProgramCpp

Ich habe vor kurzem begonnen, *.hpp Für C++ - Header zu verwenden.

Der Grund dafür ist, dass ich Emacs als primären Editor verwende und er automatisch in den C-Modus wechselt, wenn Sie eine *.h - Datei laden, und in den C++ - Modus, wenn Sie eine *.hpp - Datei laden.

Abgesehen davon sehe ich keine guten Gründe, *.h Statt *.hpp Oder umgekehrt zu wählen.

10
Serge

Ich beantworte dies als Erinnerung, um darauf hinzuweisen, dass meine Kommentare zu "user1949346" auf dasselbe OP antworten.


Also wie viele schon geantwortet haben: So oder so ist es in Ordnung. Gefolgt von Hervorhebungen ihrer eigenen Eindrücke.

Einleitend, wie auch in den zuvor genannten Kommentaren erwähnt, wird meiner Meinung nach C++ Als Header-Erweiterung .h Vorgeschlagen, wenn es tatsächlich keinen Grund dafür gibt.

Da die ISO/IEC-Dokumente diese Notation von Header-Dateien verwenden, kommt in ihren Sprachdokumentationen zu .hpp Keine Zeichenfolge vor, die mit C++ Übereinstimmt.

Aber ich strebe jetzt einen akzeptablen Grund an, WARUM so oder so in Ordnung ist und vor allem, warum es nicht Gegenstand der Sprache ist, die es selbst ist.

Auf geht's.

Die Dokumentation C++ (Ich beziehe mich eigentlich auf die Version N3690) definiert, dass ein Header der folgenden Syntax entsprechen muss:

2.9 Kopfzeilennamen

header-name:
    < h-char-sequence >
    " q-char-sequence "
h-char-sequence:
    h-char
    h-char-sequence h-char
h-char:
    any member of the source character set except new-line and >
q-char-sequence:
    q-char
    q-char-sequence q-char
q-char:
    any member of the source character set except new-line and "

Wie wir aus diesem Teil extrahieren können, kann der Name der Header-Datei auch im Quellcode gültig sein. Mit Ausnahme von '\n' - Zeichen und abhängig davon, ob es durch <> Eingeschlossen werden soll, darf es kein > Enthalten. Oder anders herum, wenn es durch "" Eingeschlossen wird - Include darf kein " Enthalten.

Mit anderen Worten: Wenn Sie eine Umgebung hatten, die Dateinamen wie prettyStupidIdea.> Unterstützt, können Sie Folgendes angeben:

#include "prettyStupidIdea.>"

wäre gültig, aber:

#include <prettyStupidIdea.>>

wäre ungültig. Umgekehrt das Gleiche.

Und sogar

#include <<.<>

wäre ein gültiger inkludierbarer Header-Dateiname.

Sogar dies würde C++ Entsprechen, es wäre eine ziemlich dumme Idee, obwohl.

Und deshalb gilt auch .hpp.

Aber es ist nicht das Ergebnis der Komitees, die Entscheidungen für die Sprache treffen!

Das Diskutieren über die Verwendung von .hpp Ist dasselbe wie über .cc, .mm Oder was auch immer ich in anderen Posts zu diesem Thema gelesen habe.

Ich muss zugeben, dass ich keine Ahnung habe, woher .hpp Kam1, aber ich wette, ein Erfinder irgendeines Analysetools, IDE oder etwas anderes, das sich mit C++ befasst, ist auf diese Idee gekommen, um einige interne Prozesse zu optimieren oder nur um einige (wahrscheinlich sogar) zu erfinden für sie notwendig) neue Namenskonventionen.

Aber es ist nicht Teil der Sprache.

Und wann immer man beschließt, es so zu benutzen. Mag sein, dass es ihm am besten gefällt oder dass es für einige Anwendungen des Workflows erforderlich ist, niemals2 ist eine Anforderung der Sprache. Wer also sagt, "das pp ist, weil es mit C++ verwendet wird", ist in Bezug auf die Sprachdefinition einfach falsch.

C++ erlaubt alles, was sich auf den vorherigen Absatz bezieht. Und wenn das Komitee irgendetwas vorschlägt, dann verwendet es .h, Da dies die in allen Beispielen des ISO-Dokuments angeführte Erweiterung ist.

Fazit:

Solange Sie keine Notwendigkeit sehen/spüren, .h Anstelle von .hpp Zu verwenden oder umgekehrt, sollten Sie sich nicht darum kümmern. Weil beide einen gültigen Headernamen mit der gleichen Qualität in Bezug auf den Standard bilden würden. Und daher ist alles, was [~ # ~] erfordert, dass [~ # ~] Sie .h Oder .hpp Verwenden eine zusätzliche einschränkung des standards, die sogar anderen zusätzlichen einschränkungen widersprechen könnte, stimmt nicht überein. Da OP jedoch keine zusätzlichen Spracheinschränkungen erwähnt, ist dies die einzig richtige und akzeptable Antwort auf die Frage

" *. h oder * .hpp für Ihre Klassendefinitionen " lautet:

Beide sind gleichermaßen korrekt und anwendbar, solange keine externen Einschränkungen vorliegen.


1Soweit ich weiß, ist es anscheinend das Boost-Framework, das diese .hpp - Erweiterung hervorgebracht hat.

2Natürlich kann ich nicht sagen, was einige zukünftige Versionen mit sich bringen werden!

8
dhein

Ich bevorzuge .hpp für C++, um sowohl den Editoren als auch anderen Programmierern klar zu machen, dass es sich eher um einen C++ - Header als um eine C-Header-Datei handelt.

6
JohnMcG

C++ ("C Plus Plus") macht als .cpp Sinn

Header-Dateien mit der Erweiterung .hpp haben nicht den gleichen logischen Ablauf.

6
Dynite

Sie können Ihre Includes nach Belieben aufrufen.

Sie müssen nur den vollständigen Namen in #include Angeben.

Ich schlage vor, wenn Sie mit C arbeiten, .h Zu verwenden, und wenn Sie mit C++ .hpp Verwenden.

Es ist am Ende nur eine Konvention.

6
slashmais

In einem meiner Jobs in den frühen 90ern haben wir .cc und .hh für Quell- und Header-Dateien verwendet. Ich bevorzuge es immer noch gegenüber allen Alternativen, wahrscheinlich weil es am einfachsten zu tippen ist.

5
camh

Codegear C++ Builder verwendet .hpp für Header-Dateien, die automatisch aus Delphi-Quelldateien generiert werden, und .h-Dateien für Ihre "eigenen" Header-Dateien.

Wenn ich also eine C++ - Headerdatei schreibe, verwende ich immer .h.

5
Roddy

Wie viele hier bereits erwähnt haben, bevorzuge ich auch die Verwendung von .hpp für reine Header-Bibliotheken, die Vorlagenklassen/-funktionen verwenden. Ich bevorzuge die Verwendung von .h für Header-Dateien, die von .cpp-Quelldateien oder freigegebenen oder statischen Bibliotheken begleitet werden.

Die meisten Bibliotheken, die ich entwickle, basieren auf Vorlagen und müssen daher nur Header sein. Beim Schreiben von Anwendungen neige ich jedoch dazu, die Deklaration von der Implementierung zu trennen und die Dateien .h und .cpp zu erhalten

4
Enzo

Bjarne Stroustrup und Herb Sutter haben eine Erklärung zu dieser Frage in ihren C++ Core-Richtlinien: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#S-source which verweist auch auf die neuesten Änderungen in der Standarderweiterung (C++ 11, C++ 14 usw.)

SF.1: Verwenden Sie ein .cpp-Suffix für Codedateien und .h für Schnittstellendateien, wenn Ihr Y-Projekt nicht bereits einem anderen Konventionsgrund folgt

Es ist eine langjährige Konvention. Konsistenz ist jedoch wichtiger. Wenn Ihr Projekt also etwas anderes verwendet, befolgen Sie dies. Hinweis

Diese Konvention spiegelt ein allgemeines Verwendungsmuster wider: Überschriften werden beim Kompilieren häufiger mit C geteilt, da C++ und C in der Regel .h verwenden, und es ist einfacher, alle Überschriften .h zu benennen, anstatt nur für die beabsichtigten Überschriften unterschiedliche Erweiterungen zu haben Für C freigegebene Implementierungsdateien werden dagegen nur selten für C freigegeben und sollten daher in der Regel von C-Dateien unterschieden werden. Daher ist es normalerweise am besten, allen C++ - Implementierungsdateien einen anderen Namen zu geben (z. B. ".cpp").

Die spezifischen Namen .h und .cpp sind nicht erforderlich (nur als Standard empfohlen) und andere Namen sind weit verbreitet. Beispiele sind .hh, .C und .cxx. Verwenden Sie solche Namen entsprechend. In diesem Dokument bezeichnen wir .h und .cpp> als Kurzform für Header- und Implementierungsdateien, auch wenn die tatsächliche Erweiterung unterschiedlich sein kann.

Ihre IDE (wenn Sie eine verwenden) kann starke Meinungen über genügen.

Ich bin kein großer Fan dieser Konvention, denn wenn Sie eine beliebte Bibliothek wie boost verwenden, ist Ihre Konsistenz bereits fehlerhaft und Sie sollten besser .hpp verwenden.

4
ruuns

Zum Glück ist es einfach.

Sie sollten die Erweiterung .hpp verwenden, wenn Sie mit C++ arbeiten, und Sie sollten .h für C verwenden oder C und C++ mischen.

3
Nykal

Ich benutze .h, weil Microsoft genau das verwendet und deren Codegenerator erstellt. Sie müssen nicht gegen den Strich gehen.

2
Mark Ransom

In "Die C++ - Programmiersprache, dritte Ausgabe von Bjarne Stroustrup", dem meistgelesenen C++ - Buch, verwendet er * .h. Daher gehe ich davon aus, dass die beste Vorgehensweise darin besteht, * .h zu verwenden.

* .Hpp ist aber auch in Ordnung!

1
user1949346

Es ist für Werkzeuge und Menschen einfach, etwas zu unterscheiden . Das ist es.

Bei herkömmlicher Verwendung (durch Boost usw.) kann .hpp ist speziell C++ - Header. Auf der anderen Seite, .h gilt nur für Nicht-C++ - Header (hauptsächlich C). Das genaue Erkennen der Sprache des Inhalts ist im Allgemeinen schwierig, da es viele nicht triviale Fälle gibt, sodass ein gebrauchsfertiges Tool aufgrund dieses Unterschieds häufig einfach zu schreiben ist. Für Menschen ist es, sobald sie die Konvention erhalten haben, auch leicht zu merken und leicht zu verwenden.

Ich möchte jedoch darauf hinweisen, dass die Konvention selbst nicht immer wie erwartet funktioniert.

  • Es wird nicht durch die Angabe von Sprachen erzwungen, weder C noch C++. Es gibt viele Projekte, die nicht der Konvention folgen. Sobald Sie sie zusammenführen (mischen) müssen, kann dies problematisch sein.
  • .hpp selbst ist nicht die einzige Wahl. Warum nicht .hh oder .hxx? (Allerdings benötigen Sie normalerweise mindestens eine herkömmliche Regel für Dateinamen und Pfade.)

Ich persönlich benutze beide .h und .hpp in meinen C++ Projekten. Ich folge der obigen Konvention nicht, weil:

  • Die von den einzelnen Projektteilen verwendeten Sprachen werden explizit dokumentiert. Keine Chance, C und C++ im selben Modul (Verzeichnis) zu mischen. Jede 3rd-Party-Bibliothek muss dieser Regel entsprechen.
  • Die von den Projekten verwendeten konformen Sprachspezifikationen und zulässigen Sprachdialekte werden ebenfalls dokumentiert. (Tatsächlich dokumentiere ich sogar die Quelle der verwendeten Standardfunktionen und Fehlerbehebung (auf dem Sprachstandard) .) Dies ist etwas wichtiger als die Unterscheidung der verwendeten Sprachen, da es zu fehleranfällig ist und die Testkosten (z. B. Kompatibilität mit Compilern) können erheblich (kompliziert und zeitaufwendig) sein, insbesondere in einem Projekt, das bereits in fast rein C++ vorliegt. Dateinamen sind zu schwach, um damit umzugehen.
  • Selbst für denselben C++ - Dialekt gibt es möglicherweise wichtigere Eigenschaften, die für den Unterschied geeignet sind. Siehe zum Beispiel die unten stehende Konvention.
  • Dateinamen sind im Wesentlichen Teile fragiler Metadaten. Der Verstoß gegen die Konvention ist nicht so leicht zu erkennen. Um im Umgang mit Inhalten stabil zu sein, sollte ein Tool letztendlich nicht nur von Namen abhängen. Der Unterschied zwischen Erweiterungen ist nur ein Hinweis. Werkzeuge, die es verwenden, sollten sich auch nicht immer gleich verhalten, z. Spracherkennung von .h Dateien auf github.com. (Es kann in Kommentaren wie Shebang etwas geben, damit diese Quelldateien bessere Metadaten sind, aber es ist auch nicht konventionell wie Dateinamen, also auch nicht zuverlässig im Allgemeinen.)

Ich benutze normalerweise .hpp in C++ - Headern und die Header sollten auf nur Header Weise verwendet (beibehalten) werden, z. als Template-Bibliotheken. Für andere Überschriften in .h, entweder gibt es ein entsprechendes .cpp -Datei als Implementierung, oder es handelt sich um einen Nicht-C++ - Header. Letzteres ist trivial, um den Inhalt des Headers nach Menschen (oder nach Tools mit explizit eingebetteten Metadaten, falls erforderlich) zu unterscheiden.

1
FrankHB

Die Erweiterung der Quelldatei kann für Ihr Build-System von Bedeutung sein. Sie haben beispielsweise möglicherweise eine Regel in Ihrem Makefile für .cpp - oder .c - Dateien oder Ihren Compiler (z. B. Microsoft cl.exe) Kompiliert die Datei je nach Erweiterung möglicherweise als C oder C++.

Da Sie für die Direktive #include Den gesamten Dateinamen angeben müssen, ist die Header-Dateierweiterung irrelevant. Wenn Sie möchten, können Sie eine .c - Datei in eine andere Quelldatei einfügen, da es sich nur um ein Text-Include handelt. Ihr Compiler hat möglicherweise die Option, die vorverarbeitete Ausgabe zu sichern, wodurch dies deutlich wird (Microsoft: /P Für die Vorverarbeitung in eine Datei, /E Für die Vorverarbeitung in stdout, /EP um #line Direktiven wegzulassen, /C um Kommentare beizubehalten)

Sie können .hpp Für Dateien verwenden, die nur für die C++ - Umgebung relevant sind, d. H. Sie verwenden Funktionen, die in C nicht kompiliert werden können.

0
Mike Dimmick

Es gibt keinen Vorteil für eine bestimmte Erweiterung, außer dass diese möglicherweise eine andere Bedeutung für Sie, den Compiler und/oder Ihre Tools hat. header.h Ist ein gültiger Header. header.hpp Ist ein gültiger Header. header.hh Ist ein gültiger Header. header.hx Ist ein gültiger Header. h.header Ist ein gültiger Header. this.is.not.a.valid.header Ist ein gültiger Header in Ablehnung. ihjkflajfajfklaf ist ein gültiger Header. Solange der Name vom Compiler richtig analysiert werden kann und das Dateisystem ihn unterstützt, ist er ein gültiger Header und der einzige Vorteil seiner Erweiterung ist das, was man in ihn einliest.

Abgesehen davon ist es sehr nützlich, in der Lage zu sein, Annahmen basierend auf der Erweiterung genau zu treffen. Daher ist es ratsam, einen leicht verständlichen Satz von Regeln für Ihre Header-Dateien zu verwenden. Persönlich bevorzuge ich Folgendes:

  1. Wenn bereits Richtlinien festgelegt wurden, befolgen Sie diese, um Verwechslungen zu vermeiden.
  2. Wenn alle Quelldateien im Projekt dieselbe Sprache haben, verwenden Sie .h. Es gibt keine Mehrdeutigkeit.
  3. Wenn einige Header mit mehreren Sprachen kompatibel sind, während andere nur mit einer Sprache kompatibel sind, basieren die Erweiterungen auf der restriktivsten Sprache, mit der ein Header kompatibel ist. Ein mit C oder C & C++ kompatibler Header erhält .h, Während ein mit C++ kompatibler Header, jedoch nicht C, .hpp Oder .hh Oder etwas Ähnliches erhält.

Dies ist natürlich nur eine von vielen Möglichkeiten, mit Erweiterungen umzugehen, und Sie können Ihrem ersten Eindruck nicht unbedingt vertrauen, selbst wenn die Dinge einfach erscheinen. Beispielsweise wurde erwähnt, dass .h Für normale Header und .tpp Für Header verwendet wird, die nur Definitionen für Klassenmemberfunktionen mit Vorlagen enthalten, wobei .h - Dateien Vorlagen definieren Klassen, einschließlich der Dateien .tpp, die ihre Mitgliedsfunktionen definieren (anstelle des Headers .h, der direkt sowohl die Funktionsdeklaration als auch die Definition enthält). Zum anderen spiegeln viele Leute die Sprache der Überschriften immer in ihrer Erweiterung wider, auch wenn keine Möglichkeit der Mehrdeutigkeit besteht. Für sie ist .h immer ein C-Header und .hpp (oder .hh oder .hxx usw.) ist immer ein C++ - Header. Und wieder verwenden einige Leute .h Für "Header, der einer Quelldatei zugeordnet ist" und .hpp Für "Header mit allen inline definierten Funktionen".

In Anbetracht dessen würde der Hauptvorteil darin bestehen, Ihre Kopfzeilen konsistent im selben Stil zu benennen und diesen Stil für jeden, der Ihren Code untersucht, sofort sichtbar zu machen. Auf diese Weise kann jeder, der mit Ihrem üblichen Codierungsstil vertraut ist, mit einem kurzen Blick feststellen, was Sie mit einer bestimmten Erweiterung meinen.

0
Justin Time