C++ Include Probleme

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • C++ Include Probleme

    Hallo,

    ich habe hier mehrere Klassen und eine Struktur. Die Klassen und die Struktur sind in unterschiedlichen Dateien gespeichert.


    Nun aber brauche ich die Struktur in mehreren Klassen und auch in meiner Main Funktion. Wie und wo füge ich die Struktur ein ohne das der Compiler mir eine Fehlermeldung ausgibt?

    Ich habe bereits versucht die Struktur auf der main.cpp (hier liegt halt meine main Funktion) zu aller erst einzufügen und anschließend die Klassen - ohne Erfolg. Sobald ich die Struktur auf den einzelnen Klassendateien einfüge, so gibt der Compiler mir eine Fehlermeldung bezüglich einer Neudefinition.


    Kann man irgendwie globale definitionen schaffen (Oder auch globale Variablen festlegen) die für das gesamte Projekt zugänglich sind? Also auch innerhalb der Klassen.
  • Die Lösung hier nent sich Include-Wächter.

    Einfachstes Beispiel:

    an den Anfang jeder Headerdatei schreibst du

    Quellcode

    1. #ifndef MY_HEADERNAME_H
    2. #define MY_HEADERNAME_H


    und ans Ende

    Quellcode

    1. #endif


    Dabei natürlich MY_HEADERNAME_H durch den Namen des jeweiligen Headers ersetzen - Großbuchstaben werden dabei normalerweise Verwendet da defines.

    CodeBlocks mach das beispielsweise automatisch wenn man die Funktion verwendet ;)
    There are only 10 types of people in the world: Those who understand binary, and those who don't.

    Download meines ersten Spiels:HIER
    Über Feedback würde ich mich freuen ;)
  • "darthdespotism" schrieb:

    Die Lösung hier nent sich Include-Wächter.

    Einfachstes Beispiel:

    an den Anfang jeder Headerdatei schreibst du

    Quellcode

    1. #ifndef MY_HEADERNAME_H
    2. #define MY_HEADERNAME_H


    und ans Ende

    Quellcode

    1. #endif


    Dabei natürlich MY_HEADERNAME_H durch den Namen des jeweiligen Headers ersetzen - Großbuchstaben werden dabei normalerweise Verwendet da defines.

    CodeBlocks mach das beispielsweise automatisch wenn man die Funktion verwendet ;)


    Wow danke dir. Was genau bringt es mir die Headerfiles zu definieren bzw. warum funktioniert es so?


    Davon ab, ich hoffe du meinst die IDE Code::Blocks. Scheint ganz nett zu sein. Bekomme zwar freien Zugang zum Visual Studio Prof. von der Uni aber für ein paar gute freeware Alternativen (Die sogar unter Linux laufen) bin ich immer offen.

    Allerdings hab ichs leider noch nicht wirklich hinbekommen meine Win32/DirectX Anwendungen zu kompilieren. Naja, mal etwas in die IDE einarbeiten ;)
  • Welcome back Blue ;)
    Habe mal wieder etwas in alten Postings recherschiert...
    Inzwischen Bachelor-Student der Allgemeinen Informatik in Bocholt?

    Ihr macht DirectX? Wir machen OpenGL *freu* (Medieninformatik, Wiesbaden)

    @topic:
    Auch wenn es fast aus dem Posting eigentlich ersichtlich ist. Als Konvention verwendet man bei den Include Guards den Dateinamen als Makroname. Eben nur großgeschrieben und mit einem Unterstrich statt dem Punkt.

    Makros sollte man aber eigentlich nur für Include Guards verwenden.
    Externe Variablen die du in Klassen brauchst, solltest du lieber im Konstruktor übergeben.
    Gerne dabei als const definieren und ebenfalls groß schreiben. Aber dann sind sie wenigstens ordentlich getypt.

    Headerfiles generell sind u.a. schön für die Übersicht, weil du alle Klassenfunktionen auf einen Blick hast. Aber es hat eben auch den Vorteil, dass du so alle Funktionsprototypen fertig getippt hast und du so bei der Implementierung nicht auf die richtige Reihenfolge angewiesen bist.

    Include Guards sind wichtig, wenn du viele Klassen hast und vermeiden willst, dass eine mehrfach eingebunden wird,
  • Im Prinzip einfach: Wenn das makro noch nicht gesetzt wird, setzt man es und bindet den inhalt des Headers ein. Sonst macht man (der Compiler!) einfach nichts.

    Das Problem kommt ja daher dass du manche Header sonst mehrfach einbindest, da du sie in verschiedenen unabhängigen Teilen brauchst oder so. Durch die Include-Wächter ist dann aber sichergestellt dass der Compiler den Inhalt nur einmal übernimmt. auch wenn du sowas schreiben würdest:

    Quellcode

    1. #include "a.h"
    2. #include "a.h"
    There are only 10 types of people in the world: Those who understand binary, and those who don't.

    Download meines ersten Spiels:HIER
    Über Feedback würde ich mich freuen ;)
  • "d0nUt" schrieb:

    Welcome back Blue ;)
    Habe mal wieder etwas in alten Postings recherschiert...
    Inzwischen Bachelor-Student der Allgemeinen Informatik in Bocholt?

    Ihr macht DirectX? Wir machen OpenGL *freu* (Medieninformatik, Wiesbaden)
    [...]


    Mahlzeit auch!

    Werd in Zukunft wieder öfters hier aktiv sein und euch mit Fragen bombadieren - wobei ich bestimmt auch mal aushelfen kann ;)

    Und Student stimmt .. Zum Glück aber studier ich angewandte Informatik :)

    Unser Dozent hat ein paar Bücher geschrieben und ist total versessen auf C/C++ und DirectX. Der Typ hat doch tatsächlich eine Spieleengine geschrieben mit der wir in GIP2 ein Spiel entwerfen sollen um zur Klausur zugelassen zu werden.

    Ab dem dritten Semester gehts dann auch richtig los mit DirectX Programmierung. Hab mir allerdings die Lektüren meines Profs angeschafft und arbeite mich grad in DirectX ein. Ist eine schöne Übung, zumal es ein sehr umfangreiches Projekt zu werden scheint und ich Problemen begegne, die mir so noch nie vorgekommen sind.

    "darthdespotism" schrieb:

    Im Prinzip einfach: Wenn das makro noch nicht gesetzt wird, setzt man es und bindet den inhalt des Headers ein. Sonst macht man (der Compiler!) einfach nichts.

    Das Problem kommt ja daher dass du manche Header sonst mehrfach einbindest, da du sie in verschiedenen unabhängigen Teilen brauchst oder so. Durch die Include-Wächter ist dann aber sichergestellt dass der Compiler den Inhalt nur einmal übernimmt. auch wenn du sowas schreiben würdest:

    Quellcode

    1. #include "a.h"
    2. #include "a.h"


    Danke für die Infos!
  • Hiho,
    Bin gerade über Google auf euer Forum gestossen und bin froh, dass hier genau das Problem angesprochen wurde, das mich gerade auch beschäftigt. Habe den hier vorgeschlagenen Include-Wächter auch in meine Header-Dateien eingebaut. Das Problem der Mehrfachdefinitionen habe ich allerdings immernoch.

    Mein Projekt besteht momentan aus zwei Headern (global.h, CDirect3D.h) und zwei CPPs (main.cpp, CDirect3D.cpp).
    Der Global-Header wird von der main.cpp und vom CDirect3D-Header included. Der CDirect3D-Header wird sowohl von der main.cpp alsauch von der CDirect3D.cpp included.
    Theoretisch sollte dies doch mit den Include-Wächtern ohne Probleme möglich sein, oder? Beim Linken erhalte ich jedoch immernoch folgende Fehlermeldung(int res_x ist eine Variable, die im Global-Header definiert ist):

    Quellcode

    1. 1>main.obj : error LNK2005: "int res_x" (?res_x@@3HA) already defined in CDirect3D.obj

    Wo könnte bei mir das Problem liegen? Könnte es eventuell etwas mit den Compiler- bzw. Linkereinstellungen zu tun haben (benutze Visual Studio 2005)?
    Bin für jede Hilfe äußerst dankbar.

    Mfg Morty.
  • news://<1182955087.975067.29550@g4g2000hsf.googlegroups.com> dürfte das sein was du suchst.

    Sry dass das etwas länger gedauert hat, ist jetzt nicht das Thema das ich wunderbar erklären kann.

    Auszug:

    On Jun 27, 9:33 am, Bram Kuijper <a.l.w.kuij...@rug.nl> wrote:
    > >
    > > long int idum;
    > > long int idum2;

    Your header guards are insufficient to prevent double definition
    errors because there is more than one compilation unit including the
    header. Each .cpp which includes the header will define its own
    globals. The header guard only prevents a single compilation unit
    from including the header more than once. What you need to do is
    something like one of the following...

    suggestion 1: Change the declarations in your header to:

    extern long int idum;
    extern long int idum2;

    Then actually define these guys in one of your .cpp files.

    suggestion 2: Modify your header to something like:

    #ifdef DEFINE_GLOBALS
    #define GLOBAL
    #else // !DEFINE_GLOBALS
    #define GLOBAL extern
    #endif

    GLOBAL long int idum;
    GLOBAL long int idum2;

    One of your .cpp files should define "DEFINE_GLOBALS" prior to
    including this header. The only real advantage of this method over
    the 1st is that you are then guaranteed that your definition and
    declarations match.

    Suggestion 3: Encapsulate the globals into one .cpp and provide
    accessors to access/set the globals. This one is a bit of fuss, so I
    don't like it so much, but...

    long get_idum();
    set_idum(long);

    long get_idum2();
    set_idum(long);

    then in a .cpp you define:

    long int idum;
    long int idum2;

    long int get_idum()
    {
    return idum;
    }

    void set_idum(long int v)
    {
    idum = v;
    }
    .
    .
    .


    You should also consider putting your globals in your own namespace so
    that they can't conflict with any other globals in the system.

    Hope that helps,
    joe

    There are only 10 types of people in the world: Those who understand binary, and those who don't.

    Download meines ersten Spiels:HIER
    Über Feedback würde ich mich freuen ;)