C++ Problem mit Crossinclude

Klopfer91

Grünschnabel
Moin moin,

bin eigentlich eingefleischter C# nutzer, aber muss diesesmal etwas in C++ entwickeln.
Ich habe hier 2 Klassen die sich gegenseitig kennen sollen, aber dabei ein rekursives include provozieren.
Mit #ifndef #define, #endif oder #pragma once krieg ich nur Fehlermeldungen wie "unerwartetes Dateiende"

Hier die beiden Header:
Memorie.h:
Code:
#include "Karte.h";
#include "Form1.h";
namespace MemorieC {
	using namespace System::Collections::Generic;

	public ref class Memorie
	{
	//Attribute
	private:
		int paare; //Anzahl der Paare im Spiel
		int gefundenePaare; //Anzahl der gefundenen Paare
		List<Karte^>^ kartenListe; // die Liste | zweimal das „^“ weil es 2 Klassenverweise sind
		Karte^ letzteKarte; //die Karte, die gerade umgedreht wurde
		Karte^ letzteKarte2; //Hilfsvariabel, hab ich keine besser Lösung für gefunden
		Form1^ form; //Die Form, auf der die Karten angezeigt werden sollen
		bool warten; // gibt an, ob Karten gerade umgedreht wurden und deswegen gleich automatischen umgedreht werden. Solange muss der Spieler warten!
		Timer^ timer; // der Timer, der genutzt wird, um den Spieler warten zu lassen.
		static int wartezeit = 500; //Wartezeit = 500ms = 0,5s 
	public:
		static String^ PicturePath = Application::StartupPath + "\\"; //Hierraus werden alle Bilder geladen. Also der Pfad wo die Exe liegt. Man kann hier noch Unterordner angeben. Bsp: [...] + "\\Bilder\\";  
	//Konstruktoren
	public:
		Memorie(int anzahlPaare, Form1^ anzeigeForm);
	};
}
Karte.h:
Code:
#include "Memorie.h";
namespace MemorieC {
	public ref class Karte : public System::Windows::Forms::PictureBox
	{
	//Attribute
	public:
		static int width = 50; //Breite einer Karte | static heißt: kann nicht zur Laufzeit geändert werden (Der Compiler akzeptiert auch keine "width = x"angabe)
		static int height = 50; //Höhe einer Karte
		int index; // der Index der Karte, gibt an um welche Karte es sich handelt und welches Bild sie hat
		int x; //gibt an in welcher horizontalen Reihe auf dem Spielfeld sich die Karte befindet
		int y; //gibt an in welcher vertikalen Reihe auf dem Spielfeld sich die karte befindet
		static System::String^ upperImage = "back.png"; // der Name des Bildes, welches die Rückseite jeder Karte zeigt
		System::String^ downImage; // der Name des Bildes, welches die Vorderseite zeigt (abhängig vom Index)
	public:
		Karte(int index, int x, int y, Memorie^ memorie);
	};
}
 
Hi und Willkommen bei tutorials.de :)

Das ist C++/CLI, also .NET-C++.
Kein normales. Deshalb verschoben.

edit:
; bei #includes gehören weg.
Und wie hast du es probiert, damit die Fehlermeldungen gekommen sind?
 
Und wie hast du es probiert, damit die Fehlermeldungen gekommen sind?
So :

Code:
#ifndef MEMORIE_H
#define MEMORIE_H

#include "Karte.h"
#include "Form1.h"
namespace MemorieC {
	using namespace System::Collections::Generic;

	public ref class Memorie
	{
	//Attribute
	private:
		int paare; //Anzahl der Paare im Spiel
		int gefundenePaare; //Anzahl der gefundenen Paare
		List<Karte^>^ kartenListe; // die Liste | zweimal das „^“ weil es 2 Klassenverweise sind
		Karte^ letzteKarte; //die Karte, die gerade umgedreht wurde
		Karte^ letzteKarte2; //Hilfsvariabel, hab ich keine besser Lösung für gefunden
		Form1^ form; //Die Form, auf der die Karten angezeigt werden sollen
		bool warten; // gibt an, ob Karten gerade umgedreht wurden und deswegen gleich automatischen umgedreht werden. Solange muss der Spieler warten!
		Timer^ timer; // der Timer, der genutzt wird, um den Spieler warten zu lassen.
		static int wartezeit = 500; //Wartezeit = 500ms = 0,5s 
	public:
		static String^ PicturePath = Application::StartupPath + "\\"; //Hierraus werden alle Bilder geladen. Also der Pfad wo die Exe liegt. Man kann hier noch Unterordner angeben. Bsp: [...] + "\\Bilder\\";  
	//Konstruktoren
	public:
		Memorie(int anzahlPaare, Form1^ anzeigeForm);
	};
}

#endif
Code:
#ifndef KARTE_H
#define KARTE_H

#include "Memorie.h"
namespace MemorieC {
	public ref class Karte : public System::Windows::Forms::PictureBox
	{
	//Attribute
	public:
		static int width = 50; //Breite einer Karte | static heißt: kann nicht zur Laufzeit geändert werden (Der Compiler akzeptiert auch keine "width = x"angabe)
		static int height = 50; //Höhe einer Karte
		int index; // der Index der Karte, gibt an um welche Karte es sich handelt und welches Bild sie hat
		int x; //gibt an in welcher horizontalen Reihe auf dem Spielfeld sich die Karte befindet
		int y; //gibt an in welcher vertikalen Reihe auf dem Spielfeld sich die karte befindet
		static System::String^ upperImage = "back.png"; // der Name des Bildes, welches die Rückseite jeder Karte zeigt
		System::String^ downImage; // der Name des Bildes, welches die Vorderseite zeigt (abhängig vom Index)
	public:
		Karte(int index, int x, int y, Memorie^ memorie);
	};
}
#endif
 
Passt eigentlich so.
Welche Datei hat dann ein unerwartetes Dateiende?

Und static bedeutet übrigens nicht, dass man die Variable nicht ändern kann.
Du brauchst const (bzw. static const).
 
zB meine Datei Karte.cpp
Code:
#include "StdAfx.h"
#include "Karte.h"

namespace MemorieC {
	Karte::Karte(int index, int x, int y, Memorie^ memorie)	{}
}
Sagt Visual Studio "unerwartetes Dateiende" (C1004)
oder error C2061: Syntaxfehler: Bezeichner 'Memorie' in Karte.h Z. 19 1 (Da beim Konstruktor)

Es scheint als ob er den include dann ignoriert...
 
Hi.

Wenn sich die Dateien gegenseitig einbinden, mußt du folgendermaßen vorgehen:

C++:
#ifndef PROJECT_FILE1_H
#   define PROJECT_FILE1_H

public ref class X; // Vorwärtsdeklaration

#else

public ref class X {
   ...
};

#endif
Gruß
 
@deepthroat
Wenn ich es nach deiner Methode umschreibe sieht mein Code so aus:

Code:
#ifndef MEMORIE_H
#define MEMORIE_H

public ref class Memorie;

#else

#include "Karte.h"
#include "Form1.h"
namespace MemorieC {
	using namespace System::Collections::Generic;

	public ref class Memorie
	{
	//Attribute
	private:
		int paare; //Anzahl der Paare im Spiel
		int gefundenePaare; //Anzahl der gefundenen Paare
		List<Karte^>^ kartenListe; // die Liste | zweimal das „^“ weil es 2 Klassenverweise sind
		Karte^ letzteKarte; //die Karte, die gerade umgedreht wurde
		Karte^ letzteKarte2; //Hilfsvariabel, hab ich keine besser Lösung für gefunden
		Form1^ form; //Die Form, auf der die Karten angezeigt werden sollen
		bool warten; // gibt an, ob Karten gerade umgedreht wurden und deswegen gleich automatischen umgedreht werden. Solange muss der Spieler warten!
		Timer^ timer; // der Timer, der genutzt wird, um den Spieler warten zu lassen.
		static int wartezeit = 500; //Wartezeit = 500ms = 0,5s 
	public:
		static String^ PicturePath = Application::StartupPath + "\\"; //Hierraus werden alle Bilder geladen. Also der Pfad wo die Exe liegt. Man kann hier noch Unterordner angeben. Bsp: [...] + "\\Bilder\\";  
	//Konstruktoren
	public:
		Memorie(int anzahlPaare, Form1^ anzeigeForm);
	};
}

#endif

und die Karte.h:

Code:
#ifndef KARTE_H
#define KARTE_H

public ref class Karte : public System::Windows::Forms::PictureBox;

#else

#include "Memorie.h"
namespace MemorieC {
	public ref class Karte : public System::Windows::Forms::PictureBox
	{
	//Attribute
	public:
		static const int width = 50; //Breite einer Karte | kann nicht zur Laufzeit geändert werden (Der Compiler akzeptiert auch keine "width = x"angabe)
		static const int height = 50; //Höhe einer Karte
		int index; // der Index der Karte, gibt an um welche Karte es sich handelt und welches Bild sie hat
		int x; //gibt an in welcher horizontalen Reihe auf dem Spielfeld sich die Karte befindet
		int y; //gibt an in welcher vertikalen Reihe auf dem Spielfeld sich die karte befindet
		static const System::String^ upperImage = "back.png"; // der Name des Bildes, welches die Rückseite jeder Karte zeigt
		System::String^ downImage; // der Name des Bildes, welches die Vorderseite zeigt (abhängig vom Index)
	public:
		Karte(int index, int x, int y, Memorie^ memorie);
	};
}
#endif

Nur jetzt krieg ich noch mehr Fehler:

C2027: Verwendung des unbekannten Typs 'Memorie'
C2061. Syntaxfehler 'Memorie'
C2143: Syntaxfehler : Es fehlt ',' vor ';'

Und unendlich viele weitere Fehler
 
Zuletzt bearbeitet:
Hi.

Sorry, ich hab es genau falschherum aufgeschrieben. Ändere das #ifndef in #ifdef.

Und du mußt die Klasse natürlich in beiden Fälllen im richtigen Namespace deklarieren.

Gruß
 
Code:
#ifdef MEMORIE_H
#define MEMORIE_H

namespace MemorieC {
public ref class Memorie;
}

#else

#include "Karte.h"
#include "Form1.h"
namespace MemorieC {
	using namespace System::Collections::Generic;

	public ref class Memorie
	{
	//Attribute
	private:
		int paare; //Anzahl der Paare im Spiel
		int gefundenePaare; //Anzahl der gefundenen Paare
		List<Karte^>^ kartenListe; // die Liste | zweimal das „^“ weil es 2 Klassenverweise sind
		Karte^ letzteKarte; //die Karte, die gerade umgedreht wurde
		Karte^ letzteKarte2; //Hilfsvariabel, hab ich keine besser Lösung für gefunden
		Form1^ form; //Die Form, auf der die Karten angezeigt werden sollen
		bool warten; // gibt an, ob Karten gerade umgedreht wurden und deswegen gleich automatischen umgedreht werden. Solange muss der Spieler warten!
		Timer^ timer; // der Timer, der genutzt wird, um den Spieler warten zu lassen.
		static int wartezeit = 500; //Wartezeit = 500ms = 0,5s 
	public:
		static String^ PicturePath = Application::StartupPath + "\\"; //Hierraus werden alle Bilder geladen. Also der Pfad wo die Exe liegt. Man kann hier noch Unterordner angeben. Bsp: [...] + "\\Bilder\\";  
	//Konstruktoren
	public:
		Memorie(int anzahlPaare, Form1^ anzeigeForm);
	};
}

#endif
C1014: zu viele Headerdateien (wieder dieser rekusive include)

Soll ich sonst mal das Projekt hochladen?
 

Neue Beiträge

Zurück