Seite 1 von 1

#ifndef Verständnisfrage

Verfasst: 12.12.2011, 10:12
von IlikeMyLife
Hallo alle zusammen,

nachdem ich gestern wieder einige Klassen geschrieben habe, kam mir folgende Frage auf:

ich teile meine klassen in externe dateien auf ( deklaration in .hpp und definition in .cpp ).

die .hpp-Dateien beginne ich mit folgendem Grundgerüst:

Code: Alles auswählen

#ifndef __EINEKLASSE_HPP__
#define __EINEKLASSE_HPP__
#include <iostream> // <--- Da drum geht es mir.

using namespace std;

...

#endif
ich habe schon öfter ( Foren, Fachbücher, etc ) gesehen, dass die includierten dateien, wie hier Beispielsweise die iostream noch vor die #ifndef geschrieben wird. Beides Funktioniert. Was sollte nun der Grund dafür sein, die includierten dateien noch davor zu schreiben?

Re: #ifndef Verständnisfrage

Verfasst: 12.12.2011, 10:24
von BeRsErKeR
Prinzipiell ist der richtige Weg, die Includes innerhalb des Include-Guards (das #ifdef) zu schreiben damit diese ggf. nicht doppelt inkludiert werden. Da Standardheader allerdings auch eigene Include-Guards besitzen funktioniert auch der andere Weg. Probleme gibt es dann aber wenn du einen Header inkludierst, der keinen eigenen Include-Guard besitzt und diesen vor dem #ifdef einbindest.

Weiterhin sind Include-Guards auch nicht immer notwendig. Header, die nur Klassendeklarationen enthalten benötigen z.B. prinzipiell keine.

Re: #ifndef Verständnisfrage

Verfasst: 12.12.2011, 10:52
von IlikeMyLife
dann bleibe ich bei meinem gewohnten werdegang, dass ich die includierten Dateien innerhalb der #ifndef schreibe :-)

Re: #ifndef Verständnisfrage

Verfasst: 12.12.2011, 11:19
von dot
Vielleicht noch ein kleiner Hinweis dazu: Namen die einen doppelten Underscore (__) enthalten und Namen die mit einem Underscore gefolgt von einem Großbuchstaben (_X) beginnen, sind reserviert. Wenn du ganz korrekt sein willst, solltest du dir also eine bessere Namenskonvention für deine Includeguards überlegen. Für den MSVC würd ich außerdem auch noch ein #pragma once drüberstreuen ;)

Und tu niemals ein using namespace in einen Header! Zumindest nicht, wenn der Header auf irgendeinem direkten oder indirekten Pfad mal von jemand anderem eingebunden werden könnte. Grund:

Code: Alles auswählen

#include <yourlibrary.h>
#include "mystring.h"

class Foo
{
private:
  string name;  // ERROR
public:
  ...
};

Re: #ifndef Verständnisfrage

Verfasst: 12.12.2011, 11:50
von IlikeMyLife
ist ja schon ein grund für die Bad-Programming Threads ;-)

mit #pragma once werde ich mich die nächsten Tage während meines Urlaubes auseinander setzen.

das einzige, was ich in diesem Rahmen noch als Frage habe, ist die Namenskonvention die du angesprochen hast.
Was währe in diesem Zuge denn passender? Der Name an sich sollte schon im Rahmen des Datei- beziehungsweise des Klassennamens sein.

Re: #ifndef Verständnisfrage

Verfasst: 12.12.2011, 11:52
von dot
Naja, eben was ohne __ drin oder _X am Anfang. Ich verwend normal sowas wie MYHEADER_INCLUDED.

Re: #ifndef Verständnisfrage

Verfasst: 12.12.2011, 11:57
von IlikeMyLife
vielen dank ;-) das gibt mir doch mal eine gute grundlage

Re: #ifndef Verständnisfrage

Verfasst: 12.12.2011, 16:24
von BeRsErKeR
dot hat geschrieben:Naja, eben was ohne __ drin oder _X am Anfang. Ich verwend normal sowas wie MYHEADER_INCLUDED.
Damit kann man allerdings genauso schnell auf die Nase fliegen. Besonders in der Windows-Welt. Ich handhabe das in der Regel so, dass ich den Namen des Projektes, den Dateinamen und die Dateiendung einbaue um eine größtmögliche Chance der Eindeutigkeit zu gewährleisten. Denkbar wären aber sogar UUIDs oder ähnliches.

Man sollte aber auch gucken in welchem Rahmen man programmiert. Für sich zu Hause denke ich, dass die von IlikeMyLife genannten Namen durchaus ausreichend sind.

Auf der Arbeit haben wir für große Projekte einfach sowas genutzt:

Code: Alles auswählen

#ifndef filename_h
#define filename_h
...
#endif
Das finde ich allerdings schon etwas risikoreich. Dann sollte es nämlich keine zwei gleichnamigen Dateien geben.

Re: #ifndef Verständnisfrage

Verfasst: 12.12.2011, 16:29
von Schrompf
Beserkers Lösung ist die schlichteste, damit kann man anfangen. Ich hab allerdings mal einige Stunden einen Compilerfehler gesucht, eben gerade weil die Dateinamen identisch waren. Seitdem machen wir sowas hier:

Code: Alles auswählen

#define _Verzeichnis_Datei_h_
wohlwissend, dass das Namensschema mit den Regeln für reservierte Namen kollidiert. Mir war das lieber, als die ganzen Include-Guards in der Symbolliste der Auto Completion drin zu haben. Du musst also nicht unbedingt mit einem Unterstrich anfangen, aber irgendeine Art von Präfix würde ich empfehlen, um bei Ctrl+Space nicht permanent die Include Guards mit gelistet zu bekommen.

Re: #ifndef Verständnisfrage

Verfasst: 12.12.2011, 16:51
von dot
BeRsErKeR hat geschrieben:Damit kann man allerdings genauso schnell auf die Nase fliegen. Besonders in der Windows-Welt.
Rein aus Interesse: Warum genau besonders unter Windows?
BeRsErKeR hat geschrieben:Ich handhabe das in der Regel so, dass ich den Namen des Projektes, den Dateinamen und die Dateiendung einbaue um eine größtmögliche Chance der Eindeutigkeit zu gewährleisten.
Ja, das mach ich auch so, bei MYHEADER_INCLUDED dachte ich an sowas: EZG_FRAMEWORK_H_INCLUDED
BeRsErKeR hat geschrieben:Denkbar wären aber sogar UUIDs oder ähnliches.
Gar keine schlechte Idee, aber das wär dann vermutlich doch ein wenig extrem ;)
Schrompf hat geschrieben:Mir war das lieber, als die ganzen Include-Guards in der Symbolliste der Auto Completion drin zu haben.
Gutes Argument, interessant dass mir das noch nie aufgefallen ist xD

Re: #ifndef Verständnisfrage

Verfasst: 12.12.2011, 23:40
von BeRsErKeR
dot hat geschrieben:
BeRsErKeR hat geschrieben:Damit kann man allerdings genauso schnell auf die Nase fliegen. Besonders in der Windows-Welt.
Rein aus Interesse: Warum genau besonders unter Windows?
Wenn ich von der Windows-Welt spreche rede ich hier von der WINAPI. Und in der windows.h bzw. den ganzen Headern, die diese Datei mit sich bringt gibt es sehr viele defines. Gefühlt jedenfalls Größenordnungen mehr als z.B. in den Headern, die ich auf anderen Systemen brauche. Dass diese nicht unbedingt Namen tragen, die gängigen Include-Guard-Bezeichnungen entsprechen mag vielleicht sein, aber die Chancen einer Kollision sind mMn deutlich höher, da es einfach so viele defines gibt.

Re: #ifndef Verständnisfrage

Verfasst: 15.12.2011, 09:15
von IlikeMyLife
Scheinbar ist die länge des Namens groß genug um auch längere Varianten erlauben zu können. Ich nutze mittlerweile folgende Namenskonvention:

Code: Alles auswählen

#ifndef VORNAME_NACHNAME_KLASSENNAME_HPP
#define VORNAME_NACHNAME_KLASSENNAME_HPP
Ich halte es für ziemlich ausgeschlossen, dass mein voller Vor- und Nachname + der Klassenname reserviert sein soll ;-)
für mich persönlich auch sinnvoll, da man direkt nachvollziehen kann, dass ich die Klasse geschrieben habe.

Re: #ifndef Verständnisfrage

Verfasst: 15.12.2011, 12:47
von Aramis
Mein Prefix ist INCLUDED_ (+ Projektkuerzel). Damit werden die #define's auch intuitiv in #if's nutzbar wenn man tatsaechlich mal wissen moechte ob eines inkludiert ist.

Re: #ifndef Verständnisfrage

Verfasst: 15.12.2011, 13:22
von dot
Unter dem von Schrompf erwähnten Gesichtspunkt der IntelliSense-Pollution, ist das so rum wohl auch die bessere Lösung...

Re: #ifndef Verständnisfrage

Verfasst: 16.12.2011, 10:00
von BeRsErKeR
IlikeMyLife hat geschrieben:Ich halte es für ziemlich ausgeschlossen, dass mein voller Vor- und Nachname + der Klassenname reserviert sein soll ;-)
für mich persönlich auch sinnvoll, da man direkt nachvollziehen kann, dass ich die Klasse geschrieben habe.
Dann wirds aber kompliziert, wenn mehrere Entwickler (ob parallel oder nicht) an der Datei arbeiten. Ich finde man sollte nicht unbedingt Dinge verwenden, die sich ändern können. Wenn man angeben will, wer diese Datei erstellt oder bearbeitet hat sollte man eher Kommentare verwenden. Dadurch kann man dann auch genauer werden, z.B. ausdrücken, dass jemand eine bestimmte Klasse/Funktion innerhalb der Datei geschrieben hat.

Re: #ifndef Verständnisfrage

Verfasst: 16.12.2011, 10:15
von IlikeMyLife
für mich zu hause werde ich weiterhin nach diesem Prinzip arbeiten.

@ Berserker:
An sich hast du recht, was das Bearbeiten und ändern der Klasse Betrifft. Für mich macht die Konvention mit dem eigenen Namen von daher Sinn, dass ich erstens, keine Vorhandenen Bezeichnungen verwende und zweitens, direkt sehe, ob eine klasse von mir persönlich stammt oder ob diese externer natur ist.

Dieses Thema werde ich noch weiter verfeinern.

Wenn ich ( wie gewollt ), später mit mehreren personen zusammen arbeite, werde ich in diesem punkt natürlich meinen namen weg lassen, da

Re: #ifndef Verständnisfrage

Verfasst: 16.12.2011, 10:25
von BeRsErKeR
Tu das ruhig. Im privaten Hobby-Bereich kann man vieles tun, was sonst nicht praktisch wäre. Ich wollte es nur gesagt haben, falls hier nicht ganz so erfahrene Leute reinschauen und sich ggf. deine Konvention aneignen wollen. ;)

Re: #ifndef Verständnisfrage

Verfasst: 16.12.2011, 10:46
von IlikeMyLife
BeRsErKeR hat geschrieben:Ich wollte es nur gesagt haben, falls hier nicht ganz so erfahrene Leute reinschauen und sich ggf. deine Konvention aneignen wollen. ;)
hahaha :D

du kannst in mir auch eine nicht so erfahrene person in diesem Bereich sehen :-) deswegen ist dein rat für mich um so nützlicher :-)

Re: #ifndef Verständnisfrage

Verfasst: 16.12.2011, 10:56
von dot
IlikeMyLife hat geschrieben:Für mich macht die Konvention mit dem eigenen Namen von daher Sinn, dass ich erstens, keine Vorhandenen Bezeichnungen verwende [...]
Dafür gibts namespace ;)
IlikeMyLife hat geschrieben:[...] und zweitens, direkt sehe, ob eine klasse von mir persönlich stammt oder ob diese externer natur ist.
Das hat Microsoft sich auch gedacht als sie die MFC geschrieben haben (man beachte dass dies zu einer Zeit geschah da es namespace noch nicht gab).
Aber irgendwie hat alle Welt dann gedacht, dass es eine gute Idee wäre diese Namenskonvention auch zu verwenden und damit war sie dann erst wieder sinnlos ;)