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

27.09.2014, 10:22

Klassen Problem

Hallo,

dieses Thema richtet sich eigentlich weniger an die Spieleprogrammierer, sondern mehr an die C++ Experten.

Also ich habe eine Klasse in einer Header und in einer anderen Header(namespace) will ich sie "Benennen"
Also ich habe die Klasse CCharacter und in dem Namespace habe ich dann CCharacter character;
aber ich bekomme vom Compiler den Fehler :
Fehlender Typspezifierer - int wird nicht angenommen. Hinweis: "Default - int " wird in C++ nicht unterstützt.

Was soll ich tun ? Was habe ich falsch gemacht ?

//Namensräume.h

C-/C++-Quelltext

1
2
3
namespace Variablen{
    CCharacter character;
};


//Character.h

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
class CCharacter{
public:
    void CreatHorst();
    void CollisionHorst();
    void MoveHorst();

    Clock clock;

    Texture Cha;
    Sprite Horst;

    

    bool IsHorstJump = true;
    bool IsSpacePressed = false;
    bool IsHorstBottom = true;

    int JumpTime = 10000;
    
    

};

Tobiking

1x Rätselkönig

  • Private Nachricht senden

2

27.09.2014, 10:45

In Namensräume.h musst du Characater.h includieren, sonst kennt er CCharacter nicht.

3

27.09.2014, 13:54

Nee, das ist nicht das Problem, Namensräume kennt schon CCharacter, mit dem includieren gibt es nur noch mehr Fehler.
In Header darf man ja nicht includieren, die kennen sich ja gegenseitig :D
Aber woran liegt es dann ? :hmm:

birdfreeyahoo

Alter Hase

Beiträge: 756

Wohnort: Schorndorf

Beruf: Junior Software Engineer

  • Private Nachricht senden

4

27.09.2014, 14:01

Namensräume kennt schon CCharacter


Daraus werde ich irgendwie nicht schlau... :hmm:

Header kennen sich selbstverständlich nicht, wie denn auch, die werden nicht mal kompiliert, sondern nur in ihren Quellcode-Dateien wo sie includiert sind.
Zeig mal deinen kompletten Code.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

27.09.2014, 14:09

Ich tippe mal auf den Standardfehler: Namensräume.h und Characater.h inkludieren sich gegenseitig...

6

27.09.2014, 16:11

Zitat

In Header darf man ja nicht includieren, die kennen sich ja gegenseitig

Man sollte so wenig inkludieren wie möglich und lieber auf Forward-Declarations setzen. Dass man es nicht darf ist Quark.

Wenn designtechnisch nicht anders möglich kannst du cyklische Abhängigkeiten durch einen define oder durch #pragma once (MS Visual C++) verhindern. Pro Kompiliereinheit wird die header dann nur einmal inkludiert:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//MyNamespace.h:
#pragma once
#include "MyClass.h"
namespace MyNamespace
{
  MyClass myGlobalVariable;
}

// MyClass.h
#pragma once
class MyClass
{
};

// MyProgram.cpp:
#include "MyNamespace.h"
#include "MyClass.h" // nicht nötig, gibt aber keine fehler (da bereits in MyNamespace.h inkludiert)!
MyNamespace::myGlobalVariable...;
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

7

27.09.2014, 16:17

Gegen zyklische Abhänigkeiten hilft weder "#pragma once" noch Include-Guards.
Da hilft nur Forward Deklaration oder die Abhänigkeit zu brechen und zum Beispiel die beiden kritischen Header nur noch über die Sources einzubinden.

"#pragma once" und Include-Guards sollte immer angewendet werden, hilft aber wirklich nur gegen Mehrfachdefinitionen durch das mehrfache Inkludieren eines Headers und nicht gegen zyklische Abhänigkeiten.

8

27.09.2014, 17:25

Zitat

Gegen zyklische Abhänigkeiten hilft weder "#pragma once" noch Include-Guards.

Wenn der Include außerhalb des Include-Guard branches bzw. überhalb der #pragma once Anweisung steht stimmt das. Aber das macht keiner und bringt keinen Sinn.

Mal ganz davon abgesehen, dass zyklische Abhängigkeiten, seien sie unterbrechbar oder nicht, auf schlechtes Design hinweisen.
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

9

27.09.2014, 17:40

Nein, es funktioniert auch sonst nicht.

Das Problem einer zyklischen Abhänigkeit ist, dass Header A eine Deklaration benötigt die sich in Header B befindet. Header B benötigt eine Deklaration die sich in Header A befindet. Dieser Endloskreislauf kann zwar mit einem Include-Guards oder "#pragma once" gebrochen werden, jedoch wird einer der Beiden Header einen Fehler verursachen, weil eine Deklaration erfordert, die sich im anderen befindet der noch nicht includiert wurde. Das ist der Fall, weil dieser andere Header bereits übergeordnet eingebunden wurde, die Deklarationen jedoch noch nicht verarbeitet wurden, weil vorher wiederum der andere Header eingebunden wurde.

Es ist nicht möglich diesem Code mit der zyklischen Abhänigkeit zu kompilieren, obwohl in dem Fall "#pragma once" verwendet wird:
HeaderA.h:

C-/C++-Quelltext

1
2
3
4
5
#pragma once
#include "HeaderB.h"

IntTypeB DoSomething();
typedef int IntTypeA;

HeaderB.h:

C-/C++-Quelltext

1
2
3
4
5
#pragma once
#include "HeaderA.h"

IntTypeA DoSomething();
typedef int IntTypeB;




Die Lösung ist schlicht und in dem Fall das Verschieben der Typedefs in einen anderen Header oder normalerweise Forward Declaration.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Spiele Programmierer« (27.09.2014, 17:46)


Werbeanzeige