Home
Über mich
Dev-Cpp
Cplusplus - Zur Sprache
Links
Tipps & Tricks
FAQ
Aktuelles
Gästebuch
 


In diesem Abschnitt behandele ich in lockerer Reihenfolge einige Themen von denen ich meine, dass sie für Einsteiger von Interesse sein könnten.

Übersicht:
Mehrfaches Einfügen (per #include) von Header Dateien verhindern

Mehrfaches Einfügen (per #include) von Header Dateien verhindern
Das Problem. Wir haben eine Funktion z.B double sqr(double x) {return (x * x;}; Die Deklaration, den Funktionsprototypen schreiben wir in die Datei bsp.h und die Definition, die Implementierung in bsp.cpp. bsp.h includieren wir durch #include "bsp.h" in bsp.cpp. Das Ganze sieht nun folgendermaßen aus:

//bsp.h
double sqr(double x);

//bsp.cpp
#include "bsp.h"
double sqr(double x) {return (x * x;}

Nun haben wir zwei Dateien foo1.cpp und foo2.cpp in denen die Funktion sqr benötigt wird. Wir includieren in beide bsp.h mittels #include "bsp.h".

// foo1.cpp
#include "bsp.h".
// Ihr Code für foo1

// foo2.cpp
#include "bsp.h".
// Ihr Code für foo2

Das Hauptprogramm:
// main.cpp
#include "foo1.h"
#include "foo2.h"

int main() {...}

Nun gibt es das erste Problem. Versuchen wir unser Programm zu kompilieren moniert der Compiler die zweifache Definition von sqr() da wir dieses zwei mal eingebunden haben (einmal über foo1 und einmal über foo2) und es daher zweimal kompiliert werden soll. Dies ist unzulässig da es zwar mehrere Deklarationen geben darf aber nur eine Definition. Die Lösung ist sich zu merken ob bsp schon einmal übersetzt wurde und dann beim zweiten Auftreten von bsp.h dieses nicht mehr zu kompilieren.
Dazu gibt es in C/C++ einen einfachen Mechanismus: Wir definieren mit Hilfe des Preprocessors eine Variable die beim ersten kompilieren gesetzt wird und beim zweiten Auftreten des Headers signalisiert "ich bin schon kompiliert".
Unser Header bsp.h sieht dann so aus:
//bsp.h
#ifndef BSP_H
#define BSP_H
  double sqr(double x);
#endif

Dies erfüllt nun genau unseren Zweck: beim ersten Auftreten von bsp.h ist die Variable BSP_H noch nicht gesetzt, d.h. die Bedingung ifndef (ist nicht definiert) wahr, BSP_H wird gesetzt und bsp kompiliert. Bei jedem weiteren Auftreten von bsp ist BSP_H gesetzt und bsp wird nicht kompiliert. Diesen Mechanismus nutzen wir für jeden Header.
Bezüglich des Namens der Variablen sind wir zwar relativ frei, aber die von mir gewählte Form vermeidet viele Probleme.

Das nächste Problem taucht in unserem Hauptprogramm auf: wir binden bsp.h zweimal ein, einmal über foo1 und einmal über foo2. Lösen läßt sich dieses Problem durch das gleiche Verfahren, nur daß wir jetzt nicht das mehrmalige kompilieren unterbinden sondern das mehrmalige includieren.
Beim ersten Auftreten, includieren von bsp.h wurde BSP_H gesetzt. Also brauchen wir nun nur noch diese Variable abzufragen und das Includieren von ihrem Status abhängig zu machen. Die Befehle dazu kennen wir schon:
// foo1.cpp
#ifndef BSP_H
  #include "bsp.h"
#endif
// Ihr Code für foo1

// foo2.cpp
#ifndef BSP_H
  #include "bsp.h"
#endif
// Ihr Code für foo2

Somit ist sichergestellt, daß bsp.h nur einmal eingebunden wird. Zu foo1 und foo2 gehören natürlich auch die entsprechenden Header, auf die der gleiche Mechanismus anzuwenden ist:
// foo1.h
#ifndef FOO1_H
  #define FOO1_H
  // Ihr Code
#endif

sowie
// foo2.h
#ifndef FOO2_H
  #define FOO2_H
  // Ihr Code
#endif

Unser Hauptprogramm sieht dann wie folgt aus:
// main.cpp
#ifndef FOO1_H
  #include "foo1.h"
#endif
#ifndef FOO2_H
  #include "foo2.h"
#endif

int main() {...}

Dies alles ist nur für eigene Header, erkennbar an den Anführungszeichen vorne und hinten, notwendig. Systemheader, erkennbar an den spitzen Klammern vorne und hinten, z.B. #include <cmath>, schützen sich selbst.

 
Top