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

1

23.10.2012, 14:03

[C++] Problem mit Headern [gelöst]

So ich hoffe ich schaff es Vernünftig zu erklären.

Und zwar hatte ich plötzlich als ich eine weitere cpp Datei hinzufügen wollte an einer stelle das Problem:

1>c:\users\shork\documents\visual studio 2010\projects\live and dead\live and dead\battle_area_managment.hpp(41): error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'skills'

Aber auch nach langem suchen bin ich nicht dahinter gekommen wo jetzt ein ; fehlen würde, vorallem hat die Zeile auf die die Fehlermeldung hindeutet schon Funktioniert und daran wurde nichts geändert. Nur hab ich nach einer weile an einer anderen Stelle den neu hinzugefügten Header ausgeklammert und plötzlich war der Fehler wieder weg. Nach längerem Probieren hab ich dann herausgefunden das ich einen von zwei Headern ausklammern muss dann geht es, diese beiden befinden sich in verschiedenen hpp Dateien. Sobald beide aktiv sind, bekomme ich den oben angezeigten Fehler wieder, dieser befindet sich aber wieder in einer anderen hpp Datei. Verstehen tu ich es aber trotzdem nicht, warum der Fehler nun kommt.

Meine Grundklasse:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef BATTLE_HPP
#define BATTLE_HPP

#include <SFML\Graphics.hpp>
#include <string>
#include <vector>
#include <fstream>

#include "framework.hpp"
#include "button.hpp"
#include "slot.hpp"
#include "read_txt.hpp"

#include "battle_area_managment.hpp"
#include "effect_managment.hpp"

class c_battle
{
    private:

        c_effect_manager ef_ma;
        c_battle_area_managment  b_a_m;
};

#endif BATTLE_HPP


Hier includiere ich das "battle_area_managment.hpp" und das "effect_managment.hpp", beide funktionieren hier Problemlos. Das "effect_managment.hpp" war die neue Klasse die ich eigentlich hinzugfügen wollte.


Dann die battle_area_managment:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#ifndef BATTLE_AREA_MANAGMENT_HPP
#define BATTLE_AREA_MANAGMENT_HPP

#include <SFML\Graphics.hpp>
#include <string>
#include <vector>
#include <fstream>

#include "framework.hpp"
#include "button.hpp"
#include "read_txt.hpp"

#include "skills.hpp"

class c_battle_area_managment
{

private:

     struct unit_data
     {
    sf::Sprite sprite;

    std::vector< c_button > skill_button;

    c_skills skills;
     };
};

#endif BATTLE_AREA_MANAGMENT_HPP


Hier tritt der Fehler auf bei dem "c_skills skills" im "unit_data" struct.


Jetzt zu der skills Datei:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef SKILLS_HPP
#define SKILLS_HPP

#include <SFML\Graphics.hpp>
#include <string>
#include <vector>

#include "read_txt.hpp"

#include "effect_managment.hpp"

class c_skills
{
};

#endif SKILLS_HPP


Hier ist der erste problematische Header, wenn ich hier "effect_managment.hpp" includiere und bei:


effect_managment.hpp:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef EFFECT_MANAGMENT_HPP
#define EFFECT_MANAGMENT_HPP

#include <SFML\Graphics.hpp>
#include <string>
#include <vector>
#include <map>

#include "read_txt.hpp"

#include "battle_area_managment.hpp"


class c_effect_manager
{
};

#endif EFFECT_MANAGMENT_HPP


Das "battle_area_managment.hpp" includiere, tritt der am Anfang genannte Fehler auf, wenn ich eines von beiden ausklammere, funktioniert es.

Zur Ergänzung noch, "read_txt" ist auch geschützt:

C-/C++-Quelltext

1
2
3
4
#ifndef READ_TXT_HPP
#define READ_TXT_HPP

#endif  READ_TXT_HPP


Mein Problem ist, ich bräuchte die beiden Headern aber um das effect System zu integrieren und an anderer Stelle kann ich sie Problemlos einfügen, in der "battle.hpp". An den anderen Stellen kommt aber plötzlich der Fehler, aber was ihn jetzt wirklich auslöst verstehe ich nicht ganz. Die Header sind ja eigentlich alle geschützt aber irgendwo scheint es mir als Vertrage sich die "skills.hpp" nicht mit der "effect_managment.hpp", nur den Grund dafür erkenne ich jetzt nicht. Hoffe ich habe das Problem gut genug erklärt.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Shorkan« (23.10.2012, 22:48)


Powerpaule

Treue Seele

Beiträge: 162

Wohnort: Berlin

Beruf: Softwareentwickler

  • Private Nachricht senden

2

23.10.2012, 14:17

Du hast dir eine include-Endlosschleife gebaut.
In c_battle inkludierst du battle_area_management, dort inkludierst du skills, dort dann effect_management und dort dann wieder battle_area_management (wo dann wieder skills usw. inkludiert wird...). Daher kennt der Compiler dann an irgendeiner Stelle einen Typen nicht mehr.
Überleg dir also nochmal, was du wirklich wo brauchst, mach die includes in der richtigen Reihenfolge in einer einzigen Header-Datei, oder lager sie soweit es geht in die cpp-Dateien aus. Stichwort: Vorwärts-Deklaration

3

23.10.2012, 14:24

Du hast dir eine include-Endlosschleife gebaut.
In c_battle inkludierst du battle_area_management, dort inkludierst du skills, dort dann effect_management und dort dann wieder battle_area_management (wo dann wieder skills usw. inkludiert wird...). Daher kennt der Compiler dann an irgendeiner Stelle einen Typen nicht mehr.
Überleg dir also nochmal, was du wirklich wo brauchst, mach die includes in der richtigen Reihenfolge in einer einzigen Header-Datei, oder lager sie soweit es geht in die cpp-Dateien aus. Stichwort: Vorwärts-Deklaration


Da er Überall Include guars hat dürfte das eigentlich nicht das Problem sein (endlosschleife), aber ich glaub dadurch das die so includiert sind weiß er, so wie Powerpaule sagt, an einer stelle nicht mehr weiter.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Koschi« (23.10.2012, 15:20)


4

23.10.2012, 15:25

@ irips

Stimmt, hatte ich wohl irgendwo mal geschrieben und dann immer mitkopiert. Visual Studio gibt mir da keine Warnung. :D


@ Powerpaule

Dann müssten ja effect_managment.hpp und battle_area_managment.hpp wenn sie sich gegeseitig includieren auch nen Fehler geben oder? Funktioniert wenn ich es so Programmiere aber problemlos, warum würde der Schritt über die skills.hpp das ändern? Oder verstehe ich die Funktion der Includeguards noch nicht ganz richtig, wie sie funktionieren? Denke mir halt wenn ich die setze, wird der Code ja nicht nochmal erstellt. Also würd er das battle_area_managment ja nicht mehr aufrufen, da es schon definiert ist oder durchläuft er den Code dann nochmal und springt deswegen wieder zurück ins battle_area_managment? :hmm: Das müsste dann ja bei den andern beiden auch sein, wenn die sich gegenseitig includieren oder geht es da einfach zufällig richtig?


@ Koschi

Dachte ich eigentlich auch, aber vllt täusche ich mich da ja.

5

23.10.2012, 15:34

Hatte mein Beitrag oben editiert.

Sind denn die Manager Klassen von ein ander abhängig?
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

6

23.10.2012, 16:44

Ah jetzt auch gesehen.

Als ich dir gerade Antworten wollte und erklären wollte wie es funktioniert, ist mir aufgefallen das ich mir nicht mehr sicher bin warum in der effect_managment.hpp das battle_area_managment includiert wird. Aber das Problem ist das ich ein ziemlich komplexes Kampfsystem erstelle für ein Taktik Spiel, wie einzelne Fertigkeiten der Charaktere erstellt werden ist schon definiert und Funktioniert schon teilweise. (Muss ich noch erweitern um paar Sachen) Das Effekte System sind eigentlich so Zustände wie Blutung oder Gift oder noch komplexere Sachen. Die will ich gerade integrieren und als ich auf den Fehler gestoßen hab war das mehr in meinem Kopf wo ich überall zugreifen muss. So vom Code habe ich da noch nichts Programmiert, da wollte ich gerade anfangen damit als der Fehler aufgetreten ist. ;)

Aber da er generell jetzt schon aufgetreten ist, frage ich mich jetzt halt, liegt das wirklich an den includes und die Guards schützen einen nicht vor so miesen Mißbrauch der includes. :D Oder ist das nur ein Nebeneffekt und ich hab sonst irgendwo noch nen Fehler der evtl. später wieder auftreten könnte. Weil wenn ich das eine mal wie oben im ersten Absatz erwähnt weglassen kann, würds ja funktionieren, aber evtl. hab ich grad auch nicht mehr im Kopf warum ich das gebraucht hab und beim Programmieren stoße ich auf das Problem wieder. Weil dann müsste ich wenns wirklich so nicht geht, dass irgendwie alles anders aufbauen und das ist sehr umfangreich. Vorallem ist die KI noch nicht integriert, die bau ich dann erst an, sobald das effect_managment funktioniert. Die muss dann auch aufs effect_managment und aufs battle_area_managment zugreifen können. Weil alle Fertigkeiten und Effekte werden in Textdateien definiert, die KI muss also am anfang alle geladenen Daten analysieren damit sie dann vernünftig Kämpfen kann. Das wird noch ein großer Spass. :crazy:

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

23.10.2012, 17:19

Du hast dir eine include-Endlosschleife gebaut.
In c_battle inkludierst du battle_area_management, dort inkludierst du skills, dort dann effect_management und dort dann wieder battle_area_management (wo dann wieder skills usw. inkludiert wird...). Daher kennt der Compiler dann an irgendeiner Stelle einen Typen nicht mehr.
Überleg dir also nochmal, was du wirklich wo brauchst, mach die includes in der richtigen Reihenfolge in einer einzigen Header-Datei, oder lager sie soweit es geht in die cpp-Dateien aus. Stichwort: Vorwärts-Deklaration


Da er Überall Include guars hat dürfte das eigentlich nicht das Problem sein (endlosschleife), aber ich glaub dadurch das die so includiert sind weiß er, so wie Powerpaule sagt, an einer stelle nicht mehr weiter.

Doch, genau das ist das Problem. Include Guards können keine zirkulären Abhängigkeiten auflösen, dafür waren sie nie und sind sie auch nicht gedacht. Die Include Guards erzeugen in diesem Fall sogar den konkreten Fehler, ohne Guards wäre der Fehler ein anderer...

Überleg dir einfach mal Schritt für Schritt, was bei diesem gegenseitigen Include passiert:

1) skills.hpp inkludiert effect_managment.hpp bevor c_skills definiert wird
2) effect_managment.hpp inkludiert battle_area_managment.hpp
3) battle_area_managment.hpp benötigt c_skills und inkludiert daher skills.hpp
4) skills.hpp wurde bereits inkludiert, daher liefert der Include Guard nur einen leeren Header
=> c_skills ist in battle_area_managment.hpp undefiniert
=> Compilerfehler

Lösung: Die zirkuläre Abhängigkeit auflösen...

Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von »dot« (23.10.2012, 17:32)


8

23.10.2012, 22:47

@ dot

Danke das hilft mir viel weiter, genauer zu verstehen was ich jetzt wirklich falsch gemacht hab und was den Fehler jetzt genau erzeugt. Dadurch kann ich das später besser vermeiden. Jetzt muss ich nur hoffen das ich eines davon weglassen kann sonst muss ich mir was anders überlegen wie ich das alles aufbaue.

Ich bin ja mal gespannt was ich Jahre später über den Code denken werde, den ich jetzt produziere, wenn ich dann mehr Einblick in die ganzen Mechaniken habe.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

9

23.10.2012, 22:49

Stichwort Forward Declaration, drakon hat mal einen guten Artikel zum Thema verfasst: http://www.drakon.ch/?id=&offset=5&mobile=0&show_entry=77 ;)

10

24.10.2012, 12:28

Ah gut zu wissen, aber wird mir glaube ich bei meinem Code nicht soviel bringen, ich muss immer auf Funktionen von den Klassen zugreifen, deswegen brauch ich die vollständige Definition. Aber mir ist jetzt wieder das fehlende Puzzelteil eingefallen, warum ich im effect_managment auch das battle_area_managment includiert hatte. Es sind eigentlich immer nur Kleinigkeiten die ich brauchen würd und es waren immer Teile die ich am Anfang als ich den Code aufgebaut hab noch nicht vor raus sehen konnte. Aber das kann ich umgehen, ich geb die Informationen einfach an battle oder battle_area_managment zurück und über die Daten kann ich dann die passenden Befehle dort auslösen.

Werbeanzeige