009
10.01.2004, 14:58 Uhr
virtual
Sexiest Bit alive (Operator)
|
Die Aussage, man könne in einen Header reinschreiben was man will, ist so leider nicht ganz richtig. Generell darf in einem Header stets nur die Deklaration, niemals die Definition stehen, weil man sonst in das Problem doppelt definitierter Symbole reinläuft. Eine Deklaration ist eine Bekanntmachung: die sagt, daß es einen bestimmten Namen gibt (Funktionsnamen, Variablennamen), der einen bestimmten zugeordneten typen hat. Eine Definition ist hingeben eine Zuordnung von einem Namen (und Typen) zu einem Speicherbereich (der implizit belegt wird). Jede Definition ist implizit eine Deklaration, nicht jedoch umgekehrt. Dieser Code:
ist bespielsweise eine Definition. Sie sagt dem Compiler: "Bitte belege Speicher, in dem der Code, der zwischen den geschweiften Klammern steht reinpasst und nenne diesen Speicherbereich "f". Ich möchte Später den Code einfach mit dem namen "f" aufrufen können." Eine Deklaration wäre das hier:
Sie sagt: Das gibt es irgendwo eine Funktion namens "f". Lieber Compiler, kümmer dich selbst drum, wo Du sie im Speicher findest; belege aber auf gar keinen Fall Speicher dafür. Bei variablen sieht eine Definition so aus:
C++: |
int x; // Definition für x, x ist Speicher, in dem man ein int unterbringen kann
|
eine Deklaration hingegen so:
C++: |
extern int x; // Deklaration für x: es gibt irgendwo ein x, wo ein int reinpasst
|
Damit man etwas compileren kann, genügt die Deklaration für die verwendeten Namen; allerdings benötigt der Linker später dann auch die Definition. Der Sinn von Deklarationen ist vor allem, daß man damit Module vorkompilieren kann (zB in Libraries) und einfach einen Header mitliefert, der dem Compiler dann sagt: diese Namen gibt es irgendwo. Die Library wird dann vom Linker verwendet, um die Definitionen zu finden.
Ein Header darf wie gesagt nur Deklarationen enthalten. Tut man da eine Definition rein, dann kann es passieren, daß - vor allem bei mehreren SourceDateien - man plötzlich zwei definitionen zu ein und demselben Namen hat (auch enn die Definitionen identisch sind: ist nicht erlaubt, in C/C++ herscht die "One-Definition-Rule"). Beherzigt man, daß man in Headern nur Deklarationen benutzen darf, hat man schon 90% Richtig gemacht. Eine weitere Sache sind die sog. "Includeguards", die die übrigen 10% ausmachen. Ein Includeguard ist einfach ein Mechanismus, der mehrmaliges Includieren von Headern vermeidet. Sie sind unbedingt notwendig, wenn man zyklische Abh. zwischen zwei Headern hat; sie sind aber auch sinnvoll, um den Source schneller compilierebar zu machen. Üblicherweise sehen Header so aus:
C++: |
#ifndef HEADER_H_INCLUDED #define HEADER_H_INCLUDED
// your stuff goes here
#endif
|
(Dabei sollte "HEADER_H_INCLUDED" pro header Datei anders heissen). Diese Anweisung verhindern, daß die Zeile "// yout stuff goes here" mehrmals vom Compiler konsumiert wird. -- Gruß, virtual Quote of the Month Ich eß' nur was ein Gesicht hat (Creme 21) |