Header soll nur für eine Datei gelten



  • Hallo zusammen,

    ich hab hier ein kleines Problem mit ein paar Header Dateien. Ich versuch das mal zu erklären:

    Header1.h beinhaltet:
    #define TEST  1
    
    Header2.h beinhaltet
    #define TEST  2
    

    jetzt will jede von denen in unterschiedliche formulare einbinden:

    Form1.h:
    #include "Header1.h"
    
    Form2.h:
    #include "Header2.h"
    

    soweit so gut. Das macht bis jetzt auch keine Probleme.

    jetzt sollen die 2 Formulare aber einem Hauptformular zugewesen werden:

    MainForm.h:
    #include "Form1.h"
    #include "Form2.h"
    

    Und jetzt fängt der Compiler an zu meckern das es TEST schon gibt. Bei den defines spuckt er zwar viele Warnungen aus, aber wenn ich gleichnahmeige globale constaten habe, gibt es Fehlermeldungen.

    Wie kann ich das unterbinden das Header1 mit in Form2 rein gebracht wird?

    Danke schonmal



  • Hallo

    Dein Problem ist durch sogenannte Include Guards zu beheben. Umfasse alles in deinen Header-Dateien mit

    #ifndef EINDEUTIGES_SYMBOL
    #define EINDEUTIGES_SYMBOL
    // Hier dein eigentlicher Quellcode
    #endif
    

    Das EINDEUTIGE_SYMBOL kannst du frei wählen, es muß aber projektweit eindeutig sein.
    Die IDE des Builders macht dies automatisch für generierte Header, bei manuell erstellten Headern must du es gegebenfalls selber einfügen.
    Mehr zum Thema Include Guards findest du über die Suchfunktion auch im C und im C++ Forum.

    Außerdem würde ich dir raten, für normale Konstanten nicht Makros in Form von #define zu verwenden, sondern konkrete Deklarationen.
    Gerade bei den PODs reicht dafür :

    const int TEST = 1;
    

    Verwende Makros nur für Dinge, die nicht anders mit C++ Mitteln zu erreichen sind.

    bis bald
    akari



  • Danke Akari,

    aber die include Gards sind bei bei meinen Header dateien enthalten, die werden ja automatisch beim Anlegen einer neuen Unit gesetzt.

    kann es auch an etwas anderem liegen?

    Wieso sind denn Macros schlechter? Ich bin der Meinung das die weniger Speicher verbrauchen weil die doch vor dem Compilieren an die entsprechenden stellen gesetzt werden, wobei eine feste constante einen Speicherbereich belegt.
    Die defines benutze ich eigenlich immer wenn an einer Stelle ein Festwert eingetragen werden muss, aber eine einzelne Zahl im Quelltext nicht wirklich aussagekräftig ist.
    Ich lass mich da aber gerne eines besseren belehren. 😉



  • Hallo

    Sorry, da hab ich deinen Post nicht gründlich genug gelesen. Dann sind die Include Guards nicht mehr ausreichend.

    Dein Problem ist einfach, das der Compiler die beiden defines nicht mehr auseinanderhalten kann. Bei Makros verursacht das nur eine Warnung, bei Compiler-Symbolen einen Fehler (mal abgesehen davon das du beiden TEST je zwei verschiedene Werte zuweist...). Daran kannst du nur etwas ändern, wenn du entweder ein Symbol anders benennst, oder verhinderst das die beiden Header irgendwo aufeinander treffen. Zum Beispiel das die fraglichen Includes von der Header-Datei der Form1 bzw. Form2 in die jeweiligen Implementationsdateien verschoben werden. Das ist generell vorzuziehen, jeweniger includes du in Headerdateien stehen hast, desto besser.

    Und damit kommen wir auch gleich zu dem Vorteil von echten Konstanten : Diese kannst du in namespaces packen und dann auseinander halten :

    Header1.h beinhaltet:
    namespace H1
    {
    const int TEST = 1;
    // ... und der Rest
    }
    Header2.h beinhaltet
    namespace H2
    {
    const int TEST = 2;
    // ... und der Rest
    }
    

    Jetzt must du zwar bei jedem Verwenden von Symbolen aus diesen Headerdateien den namespace angeben, aber jetzt kannst du die Symbole auch auseinanderhalten :

    #include "Header1.h"
    #include "Header2.h"
    
    if (x == H1::TEST)
    ...
    if (x == H2::TEST)
    

    Sowas ist mit Makros nicht möglich, diese ignorieren namespaces.
    Desweiteren haben echte Konstanten mit einem konkreten C++ Typ, der eventuelle Mißinterpretationen verhindert und aussagekräftige Fehlermeldungen ermöglicht.

    Das alles mag sich bei einem kleinen Projekt mit ein paar einfachen #define-Werten nicht auswirken, aber in großen Projekten ist sowas sehr wichtig.

    bis bald
    akari


Anmelden zum Antworten