Visual C++ : Problem mit Klassen Instanzierung und Methodenaufruf

Klopfer91

Grünschnabel
Moin moin zusammen,
ich hatte die letzten Tage schon einige Fragen zu includes hier gestellt.

Funktioniert antscheinend auch alles, nur kann ich meine Klassen, die sich nun gegenseitig kennen sollen, nicht instanzieren.

z.B. versuch ich beim Klick auf Form1 toolStripItem "Neues Spiel" eine Instanz von meiner Klasse Memorie zu erzeugen.
Das klappt überhaupt nicht und ich versteh nicht wieso.

Form1.h

Code:
#ifdef FORM1_H

namespace MemorieC {
	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
ref class Form1;
}

#else
#define FORM1_H

#include "Memorie.h";

namespace MemorieC {
	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Collections::Generic;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;

	/// <summary>
	/// Zusammenfassung für Form1
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
		{
			this->InitializeComponent();
			//
			//TODO: Konstruktorcode hier hinzufügen.
			//
		}

	protected:
		/// <summary>
		/// Verwendete Ressourcen bereinigen.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::MenuStrip^  menuStrip1;
	private: System::Windows::Forms::ToolStripMenuItem^  neuesSpielToolStripMenuItem;
	private: System::Windows::Forms::Panel^  panel1;
	protected: 

	private:
		/// <summary>
		/// Erforderliche Designervariable.
		/// </summary>
		System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
		/// <summary>
		/// Erforderliche Methode für die Designerunterstützung.
		/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
		/// </summary>
		void InitializeComponent(void)
		{
			this->menuStrip1 = (gcnew System::Windows::Forms::MenuStrip());
			this->neuesSpielToolStripMenuItem = (gcnew System::Windows::Forms::ToolStripMenuItem());
			this->panel1 = (gcnew System::Windows::Forms::Panel());
			this->menuStrip1->SuspendLayout();
			this->SuspendLayout();
			// 
			// menuStrip1
			// 
			this->menuStrip1->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(1) {this->neuesSpielToolStripMenuItem});
			this->menuStrip1->Location = System::Drawing::Point(0, 0);
			this->menuStrip1->Name = L"menuStrip1";
			this->menuStrip1->Size = System::Drawing::Size(292, 24);
			this->menuStrip1->TabIndex = 0;
			this->menuStrip1->Text = L"menuStrip1";
			// 
			// neuesSpielToolStripMenuItem
			// 
			this->neuesSpielToolStripMenuItem->Name = L"neuesSpielToolStripMenuItem";
			this->neuesSpielToolStripMenuItem->Size = System::Drawing::Size(74, 20);
			this->neuesSpielToolStripMenuItem->Text = L"Neues Spiel";
			this->neuesSpielToolStripMenuItem->Click += gcnew System::EventHandler(this, &Form1::neuesSpielToolStripMenuItem_Click);
			// 
			// panel1
			// 
			this->panel1->Location = System::Drawing::Point(12, 27);
			this->panel1->Name = L"panel1";
			this->panel1->Size = System::Drawing::Size(268, 227);
			this->panel1->TabIndex = 1;
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(292, 266);
			this->Controls->Add(this->panel1);
			this->Controls->Add(this->menuStrip1);
			this->MainMenuStrip = this->menuStrip1;
			this->Name = L"Form1";
			this->Text = L"Memorie C++";
			this->menuStrip1->ResumeLayout(false);
			this->menuStrip1->PerformLayout();
			this->ResumeLayout(false);
			this->PerformLayout();

		}
	//Methoden
	private: System::Void neuesSpielToolStripMenuItem_Click(System::Object^  sender, System::EventArgs^  e) {
				 Memorie^ memorie = gcnew Memorie(8, this);
			 }
	public :
		void spielEnde()
		{
			MessageBox::Show("Gewonnen");
		}
		//void zeichneKarte(List<Karte^>^ karten)
		//{
		//	for each(List<Karte^>^ karte in karten)
		//	{
		//	this->panel1->Controls->Add(karte);
		//	}
		//}
	};
}

#endif

Memorie.h

Code:
#ifdef MEMORIE_H

namespace MemorieC {
ref class Memorie;
}

#else
#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   
	//Konstruktoren
	public:
		Memorie(int anzahlPaare, Form1^ anzeigeForm);
	//Methode
	public:
		void bildGedrueckt(Karte^ karte)
		{
			if(!warten)
			{
				//karte->umdrehen();
				//form->Invalidate();
				//if(letzteKarte == null)
				//{
				//	letzteKarte = karte;
				//	return;
				//}
				//if(letzteKarte->Index == karte->Index)
				//{
					gefundenePaare++;
				//	letzteKarte = null;
					checkIfWin();
				//}
				//else
				//{
					warten = true;
					timer->Start();
					//letzteKarte2 = karte;
				//}
			}
		}
	private:
		void checkIfWin()
        {
            if (gefundenePaare == paare)
            {
                //form->SpielEnde();
            }
        }
		void initNeuesSpiel()
		{
			System::Random^ rand = gcnew System::Random();
			List<int>^ intListe = fillList();
			int randomint = 0;
			int x = 0;
			int y = 0;
			int anzahlKarten = paare * 2;
			for (int i = 0; i < anzahlKarten; i++)
			{
				randomint = rand->Next(0, intListe->Count);
				//Karte^ karte = gcnew (intListe[randomint], x, y, this);
				if(x < (paare / 2 -1) ) x++;
				else
				{
					x = 0;
					y++;
				}
				//karten.Add(karte);
				intListe->RemoveAt(randomint);
			}
			//form->zeichneKarten(karten);
		}
		List<int>^ fillList()
		{
			List<int>^ list = gcnew List<int>();
			for(int i = 1; i <= paare; i++)
			{
				list->Add(i);
				list->Add(i);
			}
			return list;
		}
		void timer_tick(System::Object sender, System::EventArgs e)
		{
			timer->Stop();
			//letzteKarte->umdrehen();
			//letzteKarte2->umdrehen();
			warten = false;
			//letzteKarte = null;
		}
	};
}

#endif

Memorie.cpp

Code:
#include "StdAfx.h"
#include "Memorie.h"

namespace MemorieC{
	Memorie::Memorie(int anzahlPaare, Form1^ anzeigeForm)
	{
		paare = anzahlPaare;
		this->form = anzeigeForm;
		this->initNeuesSpiel();
		timer->Interval = 500;
		//timer->Tick += new EventHandler(timer_tick);
	}
}

Fehler:

Code:
Fehler	2	error C2512: 'MemorieC::Memorie': Kein geeigneter Standardkonstruktor verfügbar	c:\users\klopfer\desktop\memoriec++\memoriec++\Form1.h	117	1	MemorieC++
Fehler	4	error C2512: 'MemorieC::Memorie': Kein geeigneter Standardkonstruktor verfügbar	c:\users\klopfer\desktop\memoriec++\memoriec++\Form1.h	117	1	MemorieC++

Ich häng noch mal das gezippte Projekt dran.

Achja: ich habe auf diese Weise Probleme mit vielen Methoden, daher sind die meisten auskommentiert.

*BUMP*
 

Anhänge

  • MemorieC++.zip
    16,4 KB · Aufrufe: 8
Zuletzt bearbeitet:

deepthroat

Erfahrenes Mitglied
Hi.
Keiner eine Idee?
Nun mal nicht ungeduldig werden. Thread Pushing wird hier gar nicht gern gesehen und verstößt gegen die Netiquette. Wundere dich also nicht, wenn du gar keine Antworten mehr auf solche Themen bekommst.

Man kann keine unvollständig definierten Klassen instanzieren. Implementiere die Methoden in der Form1.cpp.

Evtl. solltest du nochmal das Design überdenken und einfach solche Abhängigkeiten zwischen Klassen vermeiden.

Gruß
 

Klopfer91

Grünschnabel
Ich komm eigentlich aus der C# Entwicklung, deswegen waren solche Architekturen nie ein Problem.
Wundert mich, dass es in C++ antscheinend so kompliziert ist.

Jedenfalls danke, ich werde mir eine Controller Klasse bauen, die alle Klassen kennt und steuert.

Und ich bitte um Entschuldigung, dass ich ungeduldig wurde, es sollte ein Geschenk für Bekannte werden^^