2010-10-15 4 views
10

Ich hatte gerade erst bemerkt, dass meine Programme mit der String-Klasse kompiliert wurden, ohne die <string> Header zu enthalten. Es stellt sich heraus, dass <iostream><ios_base> enthält, die wiederum <string> enthält.sollte ich einen Header enthalten, der bereits über andere Header enthalten ist?

Ist das eine schlechte Praxis und sollte ich explizit <string> einschließen? Auch wenn es sich nur um Klarheit handelt?

Ist es sicher anzunehmen, dass dies für mehr als nur den <string> Header gilt? Vielleicht ist dies implementationsspezifisch und oder ist der Standardzustand der <string> Header über und <iostream> enthalten? Stellen Sie sicher, dass jede respektierte und weit verbreitete Implementierung immer <string> enthält, sofern der Aufruf an <iostream> besteht.

+2

http://en.wikipedia.org/wiki/Incl ude_guard. Die Standardbibliothek hat sie. – Dragontamer5788

+0

Das ist ziemlich praktisch, da ich dieses Feature nicht lange eingeführt habe. Vielen Dank. – aLostMonkey

Antwort

10

Sie sollten explizit die Header der Standardbibliothek angeben, die Sie benötigen.

Es ist nicht angegeben, welche Standardbibliotheksheader von anderen Standardbibliotheksheadern enthalten sind, daher unterscheiden sich diese Details zwischen Compilern.

Ein Fall, in dem Sie können verlassen sich auf einen Header von einem anderen Header enthalten ist, wenn eine Klasse in einem Header von einer Klasse in einem anderen abgeleitet ist. Beispielsweise muss <iostream><ios_base> enthalten, da Klassen, die in <iostream> definiert sind, von Klassen abgeleitet werden, die in <ios_base> definiert sind.

+2

Wer seine Anwendung auf ein anderes Betriebssystem portieren oder Ihre App aktualisieren möchte, um mit einem anderen Compiler zu arbeiten, wird es Ihnen danken, wenn Sie dem Rat von James McNellis in dieser Angelegenheit folgen. Glauben Sie mir, ich musste in der letzten Woche mehrere vernichtende E-Mails schreiben, weil die Leute die entsprechenden Header nicht hatten. Einige andere wichtige: memset ist nicht im memory.h, das ist ein Nicht-Standard-Microsoft. Ein anderes Beispiel: Fabs und abs sind in stdlib.h, nicht math.h. – George

+3

@George: 'fabs' ist in' '. 'abs' für das formale Argument des Integraltyps ist in' ', während' abs 'für Fließkommaargument (in C++, aber ich denke nicht in C) in' 'ist. Cheers & hth., –

+0

@Alf P. Steinbach: Du hast recht mit Fabs, oops. ABS ist nur für C++ überlastet.Da wir den gleichen Code mit einem C-Compiler anstelle eines C++ - Compilers kompiliert haben, musste ich einen Haufen abs() -Aufrufe durch fabs() ersetzen. Das bekomme ich, wenn ich kein Koffein mehr habe. :) – George

7

Eine gute Vorgehensweise besteht darin, immer die Header für die Klassen, die Sie in einer bestimmten Quelldatei verwenden, einzuschließen, unabhängig davon, ob Sie wissen, dass sie in bereits enthaltenen Dateien enthalten sind.

Wenn Sie beim Refactoring Ihres Codes die Notwendigkeit für eine der übergeordneten Dateien (z. B. iostream) entfernen, kann es sehr schmerzhaft sein festzustellen, warum Ihre Anwendung nicht mehr kompiliert wird.

+3

+1 Sie haben den Submit Button 2 Sekunden vor meiner fast wörtlichen Antwort gefunden. – Anthony

+0

Wenn Sie möchten, dass Ihre Makefile-Abhängigkeiten korrekt sind, dann ist das Einschließen des Headers ein * MUSS * und kein * SOLLEN *. – jww

2

Wenn Sie einen richtigen Header (mit '#pragma once' oder dem richtigen #ifndef) mehr als einmal hinzufügen, fügt es nur ein wenig mehr Zeit zum Kompilieren hinzu (nur um den Inhalt der Header-Datei zu öffnen, zu analysieren und durchzuarbeiten) , aber nichts zu ernst, während es Ihre Dateien einfacher zu kompilieren macht, sollten sich die Umstände ändern (dh sie in ein anderes Projekt verschieben, eine Bibliothek daraus machen, usw.) Wenn Sie wirklich besorgt über die Kompilierzeit sind, fügen Sie das gleiche hinzu # ifndef vor den Header einschließlich (obwohl ich es nicht empfehlen)

dh

// header.h 
#ifndef _HEADER_H 
#define _HEADER_H 
int blahblahblah(int); 
#endif 


// cppfile.cpp 
#ifndef _HEADER_H 
#include <header.h> 
#endif 
Verwandte Themen