2016-04-25 7 views
0

Der Code ich arbeite hat mehrere Header und Quelldateien für verschiedene Klassen face.cc, face.hh, cell.cc, cell.hh edge.cc edge.hh und die Header enthalten wie diese enthält,benötigen Klärung #ifndef #define

#ifndef cellINCLUDED 
#define cellINCLUDED 

#ifndef faceINCLUDED 
#define faceINCLUDED 

ich durch http://www.cplusplus.com/forum/articles/10627/ sah und sah die Art und Weise zu schreiben Wache schließen ist

#ifndef __MYCLASS_H_INCLUDED__ 
#define __MYCLASS_H_INCLUDED__ 

So in über Code, der ich arbeite, tut Compiler automatisch versteht es sucht face.hh oder cell.hh Dateien?

bessere Frage: Schreiben __CELL_H_INCLUDED__ das gleiche wie cellINCLUDED?

+1

löschen es ist nicht, was die Makrodefinitionen haben verwenden mach mit deiner Frage. Die Makros werden verwendet, um zu vermeiden, dass die gleiche Kopfzeile zweimal eingefügt wird (dies wird jetzt zugunsten von "#pragma once" veraltet). Bitte klären Sie, was Sie wissen möchten. – trojanfoe

+0

Entschuldigung. meine Frage ist ziemlich einfach. Ich lese gerade auf diese Weise bin ich verwirrt auf, wenn "cellINCLUDED" funktioniert wie "_CELL_H_INCLUDED_" –

+1

Ja, tut es. Die einzige Voraussetzung ist, dass das Makro eindeutig ist. Das empfohlene System ist besser, würde ich sagen. – trojanfoe

Antwort

2
#ifndef __MYCLASS_H_INCLUDED__ 
#define __MYCLASS_H_INCLUDED__ 

So oben Code, an dem ich arbeite, tut Compiler automatisch versteht es sich für face.hh oder cell.hh Dateien suchen?

Nein, der Compiler versteht nicht automatisch, was Sie meinen.

Was wirklich passiert, ist, dass beim Kompilieren einer translation unit der Compiler eine Liste von global definierten MACROs enthält. Und was Sie tun, ist die MACRO __MYCLASS_H_INCLUDED__ zu definieren, wenn es nicht bereits existiert. Wenn dieses Makro definiert ist, wird bis #endif nicht vom tatsächlichen Compiler geparst. Daher können Sie für die Existenz dieses MAKRO testen, um zu bestimmen, ob die Compiler, dass die Header-Datei analysiert hat es einmal zu schließen und nur einmal in der Übersetzungseinheit ... Dies ist, weil der Compiler kompiliert dann jede Übersetzungseinheit als one flattened file (after merging all the #includes)

siehe https://en.wikipedia.org/wiki/Include_guard

Ist __CELL_H_INCLUDED__ gleiche wie cellINCLUDED zu schreiben?

Ja, es ist .... Der Grund einig lieber mit unterstrichen vorangestellte und nachgestellte MACROs für Wachen enthalten ist, weil sie extrem geringe Wahrscheinlichkeit haben je als Bezeichner verwendet werden ... aber auch hier underscore could clash with the compiler ...

ich ziehe es so etwas wie dieses: CELL_H_INCLUDED

Wenn Sie cellINCLUDED verwenden, gibt es Chancen, dass eines Tages jemand es als eine Kennung in dieser Übersetzungseinheit

+1

Sie sollten nicht Unterstreichungen bevorzugen, vor allem nicht führende Unterstriche (gefolgt von Kapital Buchstaben) und doppelte Unterstriche, da diese für die Umsetzung reserviert sind. Wenn Sie möchten, dass ein Makro extrem unwahrscheinlich als Bezeichner verwendet wird, fügen Sie eine GUID hinzu. Wenn Sie keinen einfachen Zugriff auf einen GUID-Generator haben, hängen Sie das Datum und die Uhrzeit an. Es ist nicht so, dass du dich daran erinnern musst. –

+0

@BenjaminLindley, korrigieren ... ... korrigiert. :-) – WhiZTiM

+0

hey @WhiZTiM danke für die ausführliche Beschreibung. Ich sehe, dass ich Lücken in meinem Verständnis von Makros hatte, jetzt weiß ich es besser :) Ich hatte auch nicht den Wikipedia-Artikel über den Wächter gelesen, den du verlinkt hast. es war auch sehr hilfreich. Danke noch einmal :) –

1

Die Präprozessordefinitionen haben keine besondere Bedeutung. Die einzige Voraussetzung ist, dass sie über die Module hinweg eindeutig bleiben, und deshalb ist der Dateiname typischerweise ein Teil von ihnen.

Insbesondere sind die Mechanismen zur Vermeidung von Doppel-Inclusion nicht in der Sprache "eingebacken" und verwenden einfach die Mechanik des Präprozessors.

Das heißt, jeder Compiler, der Aufmerksamkeit verdient, unterstützt heute #pragma once, und Sie könnten sich wahrscheinlich darauf festlegen.

0

Da der Link, auf den Sie verwiesen haben, sagt, "Compiler haben keine eigenen Gehirne" - also, um Ihre Frage zu beantworten, nein, die Kompilierung versteht nicht, welche bestimmten Dateien beteiligt sind. Es würde nicht einmal verstehen, dass "__cellINCLUDED" konzeptionell etwas mit einer bestimmten Datei zu tun hat.

Stattdessen die umfassen Wache einfach die Logik zwischen seiner Öffnung #ifndef und Schließen #endif davor enthalten mehrfach enthalten verhindert. Sie, als der Programmierer, sagen dem Compiler, diesen Code nicht mehrere Male zu enthalten - der Compiler macht nichts "intelligentes" allein.

0

Nein, dies sagt dem Compiler/Parser, dass, wenn dies bereits in das Programm eingegeben wurde, putave nicht schon geladen wurde.

Dies sollte an der Spitze (und haben Sie ein #endif am unteren Rand) Ihrer .h-Datei.

Nehmen wir an, Sie haben mainProgram.cpp und Tools.cpp, wobei jede dieser Dateien fileReader.h lädt. Während der Compiler kompiliert jede CPP-Datei wird es versuchen, die DateiReader.h zu laden. es sei denn, Sie sagen es nicht, es wird alle fileReader-Datei zweimal laden.

ifndef = wenn nicht definiert

so wenn Sie diese (und die #endif AFTER den gesamten Code in der h-Datei) Sie sagen:

if not defined: cellINCLUDED 
then define: cellINCLUDED with the following code: 
[code] 
end of code 

so auf diese Weise, wenn es lädt den Code in Ihrer .h-Datei ein zweites Mal, wenn er das nicht definierte Bit trifft, und ignoriert den Code beim zweiten Mal.

Dies reduziert die Kompilierzeit und bedeutet auch, dass wenn Sie einen schlechten/alten Compiler verwenden, es nicht versucht, den Code erneut zu schieben.