Vorwärtsdeklaration
-
Hallo,
ich habe gerade ein Problem mit der (meiner Meinung nach) bescheuerten Vorwärtsdeklaration des C++ Single-Pass-Compilers.
Ich habe eine Anzahl an structs, die alle untereinander verwoben sind. Ich versuche es mal an einem Beispiel zu erklären://Body.h #ifndef BODY_HEADER #define BODY_HEADER #include "Contact.h" struct Body{ bool isUnder(Contact &c); }; #endif//Contact.h #ifndef CONTACT_HEADER #define CONTACT_HEADER struct Contact{ Body *axBodies[2]; }; #endifWenn ich jetzt in meinem Hauptprogramm die Datei "Body.h" lade (mit #include), dann gibt es in der Zeile "Body *axBodies[2]" den Fehler "error C2061: Syntaxfehler: Bezeichner 'Body' ".
Ich habe dann folgendes versucht:
//main.h #include <iostream> #include <math.h> #include <stdlib.h> using namespace std; struct Body; struct Contact; #include "Body.h" #include "Contact.h"Und im Hauptprogramm dieses "Main.h" laden (ich habe die #include aus Body.h rausgenommen). Dann kriege ich in der Zeile "bool isUnder(Contact &c)" die Fehlermeldung: "error C2061: Syntaxfehler: Bezeichner 'Contact' ".
Kann mir jemand helfen, wie ich dies richtig anordne oder aufbaue, damit der Compiler nicht auf die Barrikade geht und seine Arbeit macht?
Ich hoffe das Problem ist klar genug geschildert und lösbar.
MfG,
Darth
-
Die beiden Header müssen sich nicht "inkludieren":
//Body.h #ifndef BODY_HEADER #define BODY_HEADER // Forward-Deklaration von Contact struct Contact; struct Body{ bool isUnder(Contact &c); }; #endif//Contact.h #ifndef CONTACT_HEADER #define CONTACT_HEADER // Forward-Deklaration von Body struct Boy; struct Contact{ Body *axBodies[2]; }; #endifUnd hier hast du richtig Murks gebaut:
- Verwende
cmathundcstdlibstatt der C-Headers - Die sind kein Standard! using namespace std;in einem Header? - NIEMALS!!!!
//main.h #include <iostream> #include <cmath> #include <cstdlib> #include "Body.h" #include "Contact.h"Ich habs jetzt nicht ausprobiert, aber so sollte es funktionieren...
Viel Glück
- Verwende
-
#include <iostream> #include <cmath> #include <cstdlib> #include "Body.h" #include "Contact.h"gehört auch nicht in den Header.
Nur Dinge inkludieren, die unbedingt für den Header notwendig sind!
Hier kann der Header also leer bleiben, bzw. ist überflüssig.
-
Hallo daersc,
deinen Ansatz habe ich auch schon versucht. Aber da gibt mir der Compiler den Fehler aus, dass ich das "undefinierte struct Contact" (bzw Body) verwende. Er KENNT zwar den struct, aber der ist ja noch "leer" dort.
Das iostream etc hab ich aus dem Header genommen, danke für den Tipp.
MfG,
Darth
-
Darth schrieb:
Aber da gibt mir der Compiler den Fehler aus, dass ich das "undefinierte struct Contact" (bzw Body) verwende. Er KENNT zwar den struct, aber der ist ja noch "leer" dort.
Dann hast du nicht den ganzen Code gepostet.
Auf Klassenelemente kannst du natürlich erst dann zugreifen, wenn die gesamte Klassenstruktur bekannt ist. Das ist erst in der .cpp-Datei der Fall.
-
Athar schrieb:
Auf Klassenelemente kannst du natürlich erst dann zugreifen, wenn die gesamte Klassenstruktur bekannt ist. Das ist erst in der .cpp-Datei der Fall.
Was meinst du damit?
@Darth
Du brauchst im Header Contact die Vorwärtsdeklaration von Body. Allerdings kannst du damit nur Zeiger halten. Sobald du irgendwie dereferenzieren willst, ist es mit dem Ansatz aus. Mit dem Array axBodies hälst du bisher auch nur Zeiger, daher gibt es mit dem geposteten Code an der Stelle noch keine Probleme.Der Header Body muss den Header Contact inkludieren, weil du dort nicht nur mit Zeigern auf Contact arbeitest, somit müssen die gesamten Objekteigenschaften von Contact bekannt sein.
//Contact.h #ifndef CONTACT_HEADER #define CONTACT_HEADER // Forward-Deklaration von Body struct Body; struct Contact{ Body *axBodies[2]; }; #endif//Body.h #ifndef BODY_HEADER #define BODY_HEADER #include "Contact.h" struct Body{ bool isUnder(Contact &c); }; #endif//main.h #include <iostream> #include <cmath> #include <cstdlib> #include "Body.h" #include "Contact.h" using namespace std;
-
hmpf schrieb:
Athar schrieb:
Auf Klassenelemente kannst du natürlich erst dann zugreifen, wenn die gesamte Klassenstruktur bekannt ist. Das ist erst in der .cpp-Datei der Fall.
Was meinst du damit?
In Contact.cpp und Body.cpp sind jeweils beide Header eingebunden, also kann man auch auf Member der jeweils anderen Klasse zugreifen.
-
Athar schrieb:
In Contact.cpp und Body.cpp sind jeweils beide Header eingebunden, also kann man auch auf Member der jeweils anderen Klasse zugreifen.
Weiß zwar noch immer nicht, worauf du hinaus willst, aber ich muss ja nicht alles verstehen.

-
Hallo,
danke für die Hilfe.
@Athar,
ja, ich habe nicht den ganzen Code gepostet. Das wären etwa um die 1500 Zeilen, ich habe es auf das wesentliche gekürzt, möglich dass ich dabei etwas wichtiges vergessen habe.@hmpf,
dass ich nur Zeiger verwenden darf wusste ich nicht, es stimmt dass ich da mit Referenzen arbeite (und auch andernorts). Auf Membervariabeln greife ich eigentlich nirgends zu, weil ich im h-File nur die Funktionsdeklarationen aber keine Rümpfe habe.So, nun da mir das erklärt wurde, kann ich versuchen das richtig zu basteln
Ich danke nochmal für die Hilfe.Mit freundlichen Grüssen,
Darth
-
Darth schrieb:
@hmpf,
dass ich nur Zeiger verwenden darf wusste ich nicht, es stimmt dass ich da mit Referenzen arbeite (und auch andernorts). Auf Membervariabeln greife ich eigentlich nirgends zu, weil ich im h-File nur die Funktionsdeklarationen aber keine Rümpfe habe.Referenzen und Zeiger verhalten sich gleich, was die Abhängigkeiten betrifft. Du benötigst die Definition des Typen erst bei der Dereferenzierung.
-
Hallo,
ach Mensch.. kaum hat man das Gefühl, man habe das Zeug verstanden kommt der Nächste und verwirrt einen wieder. Danke dafür Nexus

Dennoch scheint es zu funktionieren, wenn ich von "under(Contact &c)" zu "under(Contact *c)" wechsle
Da ich im Moment keinen grossen Unterschied zwischen Pointer und Referenzen sehe, ist es mir eigentlich relativ egal welche Variante ich verwende.So.. Thx

MfG,
Darth