# Klassen mit include einbinden?



## TrAgIc (22. August 2005)

Ich hab das Problem, dass ich in einer Klasse eine andere verwenden möchte, was so erstmal kein Problem sein sollte. Habe diese verwendete Klasse nun in eine eigene cpp und eine Header geschrieben. includeiere diese Header in der Klasse die die andere verweden soll. Tja, aber er kennt dann scheinbar die Klassendefinition nicht  Woran kann das liegen vergess ich was?


----------



## MCoder (22. August 2005)

Prinzipiell ist dieses Vorgehen schon mal ok.

Wo verwendest du diese Klasse, lokal innerhalb einer Methode oder als Member-Variable?
Wo hast du includiert, in .h oder .cpp?
Was genau bekommst du an Fehlern?


----------



## CodeFatal (22. August 2005)

Hi,
du hast zwar nicht verraten, mit welchem Compiler du arbeitest aber hast du evt den banalen Fehler begangen, die Dateien nicht mit in dein Projekt aufzunehmen?

Gruss Michael


----------



## FireFlow (22. August 2005)

```
// main.cpp (oder eben Klasse2... macht kein Unterschied)
#include "Klasse.hpp"

int main() { /*... */ }

// Klasse.hpp
#ifndef _KLASSE_HPP
#define _KLASSE_HPP

class Klasse
{
    public:
        Klasse();
        ~Klasse();
};

#endif

// Klasse.cpp
#include "Klasse.hpp"

Klasse::Klasse() { /* ... */ }
Klasse::~Klasse() { /* ... */ }
```

Dann noch die Klasse.cpp compillieren und mitlinken.


----------



## TrAgIc (22. August 2005)

Ok ich geb zu, hab euch ein bisschen wenig Infos mitgegeben, war ja aber auch schon spät...


```
#ifndef _SKYBOX_H
#define _SKYBOX_H

#include "JPEG.h"

#define SKYFRONT 0						// Give Front ID = 0
#define SKYBACK  1						// Give Back  ID = 1
#define SKYLEFT  2						// Give Left  ID = 2
#define SKYRIGHT 3						// Give Right ID = 3
#define SKYUP    4						// Give Up    ID = 4
#define SKYDOWN  5						// Give Down  ID = 5

class Skybox 
{
public:
	UINT SkyboxTexture[6];		// We need 6 textures for our Skybox

	void init();
	void Draw_Grid();
	void Draw_Skybox(float x, float y, float z, float width, float height, float length);
};

#endif
```

Diese Klasse ist dann in der Skybox.cpp implementiert. Und das nächste Listing ruft diese auf.


```
#ifndef _UNIVERS_H
#define _UNIVERS_H

#include "Skybox.h"

class Univers{

private: 
	Skybox _aSkyBox;
	double _sizeX;
	double _sizeY;
	double _sizeZ;

public:
	Univers(double sizeX, double sizeY, double sizeZ);
	void init();
	Skybox getSkyBox();
};

#endif
```

Und bei der Deklarierung von Skybox als private Membervariable kommt folgender Fehler:

error C2146: syntax error : missing ';' before identifier '_aSkyBox'

sowie 

error C2501: 'Univers::Skybox' : missing storage-class or type specifiers


----------



## CodeFatal (22. August 2005)

Hi, 
bin mir zwar nicht sicher obs hilft aber versuchs mal mit wenigstens Konstruktoren in beiden Klassen...

Ansonsten habe ich am prinzipiellen Aufbau nix gefunden. 

Gruss Michael


----------



## TrAgIc (22. August 2005)

Ist schon komisch.... Es sollte so vollkommen richtig sein...

Hab nu mal den gesammten Code hochgeladen, vielleicht ist es auch ein Fehler im Zusammenhang. Verwende übrigens Visual Studio 6 VC++

http://home.arcor.de/tragic/Univers.zip


----------



## alixander (23. August 2005)

Wenn du eine Datei mit #include "datei.h" einbindest, dann muss diese sich auchin dem selben Verzeichnis befinden, wie die Datei, die diese einbindet.

mfg


----------



## Endurion (23. August 2005)

Das Problem ist, dass du Cyclic Dependencies in deinen Include-Headern hast. Univers.hpp included Skybox.hpp, die included jpeg.h, die included main.h (was hat main mit jpeg zu tun?) und die included Univers.h. Mit anderen Worten, die sind beide von einander abhängig, wenn auch indirekt. Wenn du bei Skybox ja nur das UINT typedef brauchst, ersetz das doch durch "unsigned long", das es sowieso ist, oder versuch, die Abhängigkeiten ein bisschen abzugrenzen.


----------



## CodeFatal (23. August 2005)

Guten Morgen, liebe...

Ring-Include ist natürlich möglichst zu vermeiden. 
Versuch trotzdem mal den Befehl "extern".
Ist zwar auch nicht schön aber manchmal geht es halt nicht anderes.

Gruss Michael


----------



## jokey2 (23. August 2005)

Füge doch vor der Deklaration von 'class Univers' eine Vorausdeklaration von Skybox ein. Also einfach

```
class Skybox;
 
   class Univers{
  
  private: 
  	Skybox _aSkyBox;
  	double _sizeX;
 ...
```
Dann solte der Compiler sich nicht mehr beschweren.
  Allerdings stimme ich prinzipiell CodeFatal zu, daß zyklische Includes zu vermeiden sind.


----------



## MCoder (23. August 2005)

@jokey2: Die Vorausdeklaration funktioniert allerdings nur, wenn mit Zeigern gearbeitet wird.
Dein Codebeispiel  wird dem Compiler nicht gefallen


----------



## jokey2 (23. August 2005)

Ups. da hast Du recht! Sorry! Der Compiler will ja dann gleich den Konstruktor aufrufen, wenn er die Klasse Univers anlegt. Daher sollte TrAgic einen Konstruktor für Skybox implementieren. Und am Besten auch gleich einen Destruktor.


----------



## deepthroat (23. August 2005)

Hi.

Mit Anlegen (= Instanzieren) hat das erstmal nix zu tun. Dem Compiler muß allerdings die Größe der Klasse bekannt sein und dazu muß er die Größe aller Mitglieder einer Klasse wissen. Die Größe ist bei einem Pointer natürlich bekannt, nach einer Vorausdeklaration einer Klasse leider nicht.

Wenn man keinen Konstruktur anlegt, generiert der Compiler einen Standard-Konstruktur (und einen Kopier-Konstruktor). Ich finde es unnötig leere Konstruktoren zu schreiben...


----------



## TrAgIc (23. August 2005)

Ich danke euch allen! Dachte mir sowas schon, dass ich ein Fehler in den includes haben müsste. Konnte mir aber nicht erklären wo, und vor allem nicht wie. Denn durch das #ifndef wird doch die Doppeldefinition verhindert oder? Sprich ich müsste theoretisch ein und die selbe Header tausendfach includieren können, ohne Probleme. Kann mir eigentlich nur vorstellen, dass eine cyclische Einbindung zu einer Endlosschliefe führen könnte, aber das er dadurch die Typdefinition nicht rafft....


Aber danke! Werd ich nachher gleich mal ausprobieren. Hoffe ich kann dann endlich wieder an wichtigen Sachen weiterarbeiten


----------



## Endurion (23. August 2005)

Stimmt, der #ifdef-Guard hat die Doppelinkludierung verhindert. Allerdings hat eben der Header, der die erste Header-Datei erneut inkludieren will dann eben den Typ nicht (weil er ja durch die Guards den Header ignoriert hat). 

Ohne Guard hätte es einen Neudefinitionserror gegeben (oder Cyclic dependency error oder so).


----------

