Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Stupidus

Frischling

  • »Stupidus« ist der Autor dieses Themas

Beiträge: 41

Wohnort: Heilbronn

Beruf: Schöler

  • Private Nachricht senden

1

06.06.2006, 18:42

#ifndef Erklärung gesucht

Hi Leute,
ich hab mal ne Frage zu der Präprozessor-Direktive

C-/C++-Quelltext

1
#ifndef

bzw. zu dem Ausdruck

C-/C++-Quelltext

1
2
#ifndef Blablabla.hpp
#define Blablabla.hpp


Also was genau hat das zu bedeuten, hat dies für Auswirkungen, etc...
weil ich hab des net so ganzgecheckt :D .

Gruß Stupidus
Erst wenn der letzte Baum gerodet,
der letzte Fluß vergiftet, der letzte Fisch getötet ist,
dann werden die Menschen feststellen,
dass man Geld nicht essen kann!

ext

Treue Seele

  • Private Nachricht senden

2

06.06.2006, 18:46

Im ersten durchlauf ist das noch nicht definiert (#ifndef -> if not defined -> wenn x noch nicht bekannt ist, dann mach folgendes), dann wird es definiert und wenn du den Header nochmals inkludierst, dann wird der Block übersprungen, weil es definiert ist.

beispiel

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
//foo.h

#ifndef FOO_H
#define FOO_H

class Foo
{
};
#endif //gehört zu #ifndef FOO_H



//main.cpp

#include "foo.h"
#include "foo.h" //würde nen Fehler geben ohne dem Include-Guard, da ohne ihn Foo jetzt zweimal definiert wäre

Stupidus

Frischling

  • »Stupidus« ist der Autor dieses Themas

Beiträge: 41

Wohnort: Heilbronn

Beruf: Schöler

  • Private Nachricht senden

3

06.06.2006, 19:14

also stellt des sicher, dass sie nur einmal inkludiert wird?? Und wenn man die FOO.h Datei in eine andere Headerdatei einbindet, so z.B. BLA.h (bzw. deren CPP datei) und diese (Bla.h) nun in die Main datei. Kann man nun auch auf die Funktionen von FOO.h zurgeifen (von der Maindatei aus)??

Ich hoffe das dies nicht zu kompliziert beschrieben ist

Gruß Stupidus
Erst wenn der letzte Baum gerodet,
der letzte Fluß vergiftet, der letzte Fisch getötet ist,
dann werden die Menschen feststellen,
dass man Geld nicht essen kann!

ext

Treue Seele

  • Private Nachricht senden

4

06.06.2006, 19:18

Genau :)

5

06.06.2006, 21:50

Wobei man ifndef usw natürlich nicht nur in diesem bereich anwenden kann... kannst bsw. auch gebrauchen wenn du bsw. einen Singleton implementieren willst... Unter 7.1 muss das etwas anders sein als 8 ...
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

Lemming

Alter Hase

Beiträge: 550

Beruf: Schüler

  • Private Nachricht senden

6

06.06.2006, 23:45

Devil
hä wo brauchstn bei singletons #ifndef ????
Es gibt Probleme, die kann man nicht lösen.
Für alles andere gibt es C++...

Sheddex

unregistriert

7

07.06.2006, 00:29

Heiko benutz das auch in seinem Buch... und der muss es wissen, er ist ja ein "echter Pro" ;)

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

8

07.06.2006, 07:11

Also, um das nochmal ganz klar zu sagen:

Präprozessor-Befehle haben nichts damit zu tun, einen Singleton zu implementieren.

Mit Präprozessor-Befehlen wie #ifndef oder #ifdef kann man steuern, welchen Quelltext der Compiler letztendlich zu sehen bekommt, so wie das oben schon beschrieben ist. Das ist quasi wie ein "if" das schon beim Compilieren ausgewertet wird.

Was Devil meinte war vom Sinn her etwas anderes. Nehmen wir doch mal die MessageBox Methode als Beispiel, die (sinngemäß) folgendermaßen definiert ist:

C-/C++-Quelltext

1
2
3
4
5
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif

Wenn also UNICODE definiert ist (das wird gewöhnlich beim Erzeugen eines Projekts in VC++ festgelegt) soll MessageBoxW (für Wide-Character) benutzt werden, andernfalls MessageBoxA (für ASCII-Character). Das kann man sich vorstellen, als würde der Variable MessageBox der Wert MessageBox[WA] zugewiesen.

Wenn du jetzt irgendwo im Quelltext MessageBox benutzt, wird das vom Präprozessor ersetzt, bevor der Compiler den endgültigen Quelltext sieht. Das ist so, weil wir das für den Präprozessor mit #define so festgelegt haben.

#include ist auch ein Präprozessor Befehl, der nichts anders macht, als den Inhalt der angegebenen Datei an der Stelle einzufügen, wo das #include steht, und diesen dann so zu behandeln, als hätte er dort schon vorher gestanden.

Fazit: Wenn man etwas compiliert, wird der Quelltext erst durch einen Präprozessor aufbereitet, so dass ein "neuer" Quelltext entsteht, der dann erst durch den eigentlichen Compiler läuft.

Gruss,
Rainer
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

ext

Treue Seele

  • Private Nachricht senden

9

07.06.2006, 14:45

Er verwendet nen Makro sicher zur Codegenerierung, also ungefähr so:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
#define SINGLETON(class_name) public: static class_name & getSingleton() \
{ \
   static class_name class_name##_instance; \
   return class_name##_instance; \
} \

//Anwendung

class Foo
{
   SINGLETON(Foo)
};

Fred

Supermoderator

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

10

16.08.2007, 21:39

Hi,

Wieso klappt folgendes nicht?

Test.h:

C-/C++-Quelltext

1
2
3
4
5
6
#ifndef TEST_H
#define TEST_H
int hallo;
int Test;
float Wasweißich;
#endif


Test.cpp

C-/C++-Quelltext

1
#include "Test.h"


Test2.cpp

C-/C++-Quelltext

1
#include "Test.h"


Er liefert mir folgende Fehler:

Quellcode

1
2
3
Test2.obj : error LNK2005: "int Test" (?Test@@3HA) ist bereits in Test.obj definiert.
Test2.obj : error LNK2005: "float Wasweißich" (?Wasweißich@@3MA) ist bereits in Test.obj definiert.
Test2.obj : error LNK2005: "int hallo" (?hallo@@3HA) ist bereits in Test.obj definiert.


Aber egtl. müsste dies doch das #ifndef/#define verhindern.

Werbeanzeige