Registrierung Kalender Mitgliederliste Teammitglieder Suche Häufig gestellte Fragen Zur Startseite

Informatiker Board » Suche » Suchergebnis » Hallo Gast [Anmelden|Registrieren]
Zeige Beiträge 1 bis 10 von 10 Treffern
Autor Beitrag
Thema: Copy Constructor C++
Tommy

Antworten: 1
Hits: 3.293
Copy Constructor C++ 02.12.2015 16:08 Forum: Softwaretechnik


Ich habe eine kleine Unklarheit beim Erstellen eines Copy Constructors, der eine tiefe Kopie erzeugen soll:

code:
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:

CMatrix::CMatrix(int M, int N)
{
	m_rows=M;
	m_cols=N;
	m_size=m_rows*m_cols;
	m_pArray = new double[m_size];
}

CMatrix::CMatrix(const CMatrix& orig)
{

//	double* m_pArray;                             
//	m_pArray = new double[orig.m_size];   

	m_pArray = orig.m_pArray;
	m_rows = orig.m_rows;
	m_cols = orig.m_cols;
	m_size = orig.m_size;


	for (int i=0; i<m_size; i++)
		{
			m_pArray[i] = orig.m_pArray[i];
		}

		return;

}


Ich war der festen Überzeugung, dass ich erst wie im auskommentierten Teil ein neues dynamische Array erzeugen muss, mit den Variablen von dem Array das ich kopieren möchte.
Allerdings stürzt das Programm dann immer ab.

Ohne den auskommentierten Teil funktioniert das Ganze wunderbar, ich habe in meiner printfunktion mittles "this" und "&m_pArray" die Adressen der beiden Objekte und deren Arrays überprüft und festgestellt, dass sie unterschiedliche Adressen haben.

Daher gehe ich davon aus, dass die Inhalte auch in unterschiedlichen Adressen gespeichert sind, wie in einer tiefen Kopie vorgesehen.

Aber wieso?

Ich habe doch gar kein neues Array erzeugt ?

Oder ist das der Teil, der ein neues dynamisches Array erzeugt?

code:
1:
2:
3:
4:
5:
        m_pArray = orig.m_pArray;
	m_rows = orig.m_rows;
	m_cols = orig.m_cols;
	m_size = orig.m_size;


Und wenn ja, wieso muss ich dann nicht "new" benutzen ?

Liegt das daran, dass die Zeile " m_pArray = orig.m_pArray " auf die Zeile im Default Konstruktor verweist und für den Compiler so aussieht: "m_pArray = new double[m_size]" ?
Also, dass quasi der Teil hinter dem Gleichheitszeichen durch den Teil im Default Konstruktor ersetzt wird ?

Und da die Variable "m_pArray" in meiner Klassendefinition schon intitalisiert wurde, muss ich das nicht ein zweites Mal machen ?

Ich hab das Gefühl ich steh vorm Baum und seh den Wald nicht verwirrt
Thema: Dynamische Objekte und Attribute
Tommy

Antworten: 14
Hits: 9.710
09.12.2014 10:23 Forum: Softwaretechnik


Läuft Tanzen

Und zwar noch besser als vorher!
Bei meiner vorherigen Lösung passierte bei der ersten Eingabe nichts.
Jetzt reagiert der Roboter sofort Daumen hoch
Thema: Dynamische Objekte und Attribute
Tommy

Antworten: 14
Hits: 9.710
09.12.2014 10:09 Forum: Softwaretechnik


Saugeil ! großes Grinsen großes Grinsen
Danke Gott

Jetzt habe ich nur ein kleines Problem mit der Schleife:

code:
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:
31:
32:

        World pworld;
	CVacubot Saugi;
	Saugi.setWorld(&pworld);

	string key = pworld.getKey();

do
		{
				string key = pworld.getKey();

				cout <<"Eingabe: "<< key <<endl;

				if (key == "up")
					{Saugi.setMovement(1);}

				if (key == "left")
					{Saugi.setAlignment(45);}

				if (key == "right")
					{Saugi.setAlignment(-45);}

				if (key == "e")
					{break;}

		}

while (key != "e");
return 0;



Wenn ich "string key = getKey();" nicht in die Schleife packe, dann dreht sich der Roboter immer nur im Kreis. Wenn ich es in sowohl in als auch ausserhalb der Schleife stehen habe, dann funktioniert meine while Bedingung nicht mehr, ausser, ich schreibe in der while Bedingung wieder "while (get.Key() != "e")" was dann aber wieder zu mehrfachem drücken von Tasten führt.
Meine Brechstangen-Lösung war jetzt eine break Bedingung.
Ich habe irgendwo gelesen, dass ich dafür in die Hölle komme, zusammen mit "goto"-Usern LOL Hammer
Thema: Dynamische Objekte und Attribute
Tommy

Antworten: 14
Hits: 9.710
08.12.2014 20:54 Forum: Softwaretechnik


Die Aufgabe wurde mittlerweile erweitert und zwar sollen wir nun den Roboter per Eingabe steuern.
Dazu ist in der Klasse World die Methode "getKey()" implementiert.
Wir haben ein Aktivitätsdiagramm bekommen, nach dem wir diese methode implementieren sollen.
Sieht bei mir so aus:

code:
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:
31:
32:
33:
34:

World pworld;
CVacubot Saugi;
Saugi.setWorld(&pworld);

	do
	{
			pworld.getKey();

			cout <<"Inhalt von getKey: "<< pworld.getKey() <<endl << endl;


				if (pworld.getKey() == "up")
		{
		Saugi.setMovement(1);
		}

				if (pworld.getKey() == "left")
		{
		Saugi.setAlignment(45);
		}

				if (pworld.getKey() == "right")
		{
		Saugi.setAlignment(-45);
		}


	}
		while (pworld.getKey() != "e");
		return 0;



Läuft auch, aber ... man muss 3-4 mal dieselbe Taste drücken bis etwas passiert.
Woran liegt das ?
Thema: Dynamische Objekte und Attribute
Tommy

Antworten: 14
Hits: 9.710
08.12.2014 20:51 Forum: Softwaretechnik


Das Hauptproblem war, dass ich die Methode setWorl ganz am Anfang hätte aufrufen müssen, und dann erst die setAlignment und setMovement Methoden

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:

World pworld;
CVacubot Saugroboter;
Saugroboter.setWorld(&pworld);
Saugroboter.setAlignment(90);
Saugroboter.setMovement(1);




Und natürlich wie Du auch beschrieben hast in der setWorld Methode die übergebene Welt als aktuelle Welt.

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:

void CVacubot::setWorld(World* pWorld)
{

	m_World = pWorld;
	if (m_World!=NULL)
	m_World->show(m_X, m_Y, m_Alpha, m_Diameter);

}



Danke für Deine Hilfe !
Man da liegt echt noch ein weiter Weg vor mir ... aber das Gefühl, wenn nach Tagen des rumfrickeln endlich alles funktioniert ist echt toll :-D
Thema: Dynamische Objekte und Attribute
Tommy

Antworten: 14
Hits: 9.710
02.12.2014 17:37 Forum: Softwaretechnik


Entschuldige bitte, ich dachte ich hätte alle notwendigen Informationen geliefert.

Erstmal die Aufgabe:

Zitat:

Um die Bewegung des Saugroboters veranschaulichen zu können, steht Ihnen eine graphische Konsole zur Verfügung. Natürlich müssen Sie dieser konsole für eine korrekte Anzeige die aktuelle Position des Saugroboters "bekanntgeben". Das soll in dieser Aufgabe implementiert werden.

a) Die Konsole wird zunächst unabhängig von Eclipse gestartet. Geben Sie dazu im Browser den Link "ich darf keine URLs posten" ein.
Die Konsole läuft unabhängig von Ihrem Programm und muss im Normalfall nicht mehr beendet werden.

b) Um die Konsole aus Ihrem Programm ansprechen zu können, ergänzen Sie in der Header-Datei Ihrer Saugroboterklasse die Anweisung 'include "cleanerbot/World.h".
Damit steht Ihnen eine Klasse "World" zur Verfügung.
Sie benötigen zunächst nur die Methode show(double positionX, double positionY, double angle, double diameter=0.4).
Der Aufruf dieser Methode veranlasst die Konsole einen saugroboter an der angebeben Stelle mit der angegebenen Ausrichtung anzuzeigen bzw ihn an die angegebene Stelle zu bewegen.

Ergänzen Sie nun in der Implementierung ihrer Saugroboterklasse ein Attribut World* m_world mit dem Inititalwert NULL. Ergänzen Sie weiter die Methode "void setWorld(World* world)", die dem Attribut den übergebenen Wert zuweist.

Fügen Sie in der Implementierun ihrer Klasse in allen Methoden, die die Position verändern einen Aufruf der Methode show(..) des neuen Attributs m_World ein.
Rufen Sie die Methode auch on der setWorld Methode auf.

Ergänzen Sie Ihre Saugroboterklasse außerdem um einen Destruktor in dem die show-Methode von m_world mit dem Wert 0 für den Durchmesser aufgerufen wird, um den Saugroboter wieder aus der Darstellung zu entfernen.

Beachten Sie bei allen Änderungen, dass Ihre Saugroboterklasse auch dann weiter lauffähig sein soll, wenn keine "Welt" bekannt ist, dh wenn das Attribut m_world den Wert NUL hat.

c) Erweitern Sie Ihr Testprogramm aus Übung 2, Aufgabe 2c. Ergänzen Sie zu Beginn die Deklaration eines Objekts vom Typ "World" (noch bevor Sie Ihren Saugroboter deklarieren) und machen Sie das Objekt Ihrem Saugroboter mit setWOrld bekannt.
Wiederholen Sie die Steueranweisungen des Test mit ihrem Saugroboter, der sich jetzt in einer Welt bewegt und beobachten Sie die Konsole.


CVacubot.h
code:
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:
31:
//#ifndef CVACUBOT_H_
#define CVACUBOT_H_

#include "cleanerbot/World.h"
//#include "CPoint.h"
class CVacubot {

private:
	double m_Diameter;
	double m_X;
	double m_Y;
	double m_Alpha;
	int m_M;
	World* m_World;
	//CPoint* position;

public:
	CVacubot();
	~CVacubot();
	double getPosition();
	double getAlignment();
	double setAlignment(double Alpha);
	int setMovement(int M);
	void print();
	void setWorld(World* world);

};

//#endif /* CVACUBOT_H_ */



CVacubot.cpp
code:
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:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
#include <iostream>
#include <stdlib.h>
#define _USE_MATH_DEFINES
#include <cmath>
using namespace std;
#include "CVacubot.h"
#include "cleanerbot/World.h"
//#include "CPoint.h"

CVacubot::CVacubot()
{
	m_X=0;
	m_Y=0;
	m_Diameter=0.4;
	m_Alpha=0;
	m_M=0;
	//m_World=0;
	//position=0,0;
}

void CVacubot::setWorld(World* world)
{

World* positionX=&m_X;
World* positionY=&m_Y;
World* angle=&m_Alpha;
World* diameter=&m_Diameter;
m_World->show(m_X, m_Y, m_Alpha, m_Diameter=0.4);

return;
}

double CVacubot::setAlignment(double Alpha)
{
	m_Alpha=((Alpha*M_PI)/180)+m_Alpha;
	m_World->show(m_X, m_Y, m_Alpha, m_Diameter);
	return true;
}

int CVacubot::setMovement(int M)
{
	m_M=M;
	m_X=m_M*cos(m_Alpha)+m_X;
	m_Y=m_M*sin(m_Alpha)+m_Y;
	m_World->show(m_X, m_Y, m_Alpha, m_Diameter);
	return true;
}

double CVacubot::getAlignment()
{
	return m_Alpha;
}

double CVacubot::getPosition()
{
	return m_X;
	return m_Y;
}

void CVacubot::print()
{
	double Alpha;
	Alpha=(m_Alpha*180)/M_PI;
	m_X=(int)(m_X*100+0.5)/100.0;
	m_Y=(int)(m_Y*100+0.5)/100.0;
	cout << "Die Ausrichtung des Saugroboters beträgt: "<<m_Alpha<<" radians ("<<Alpha<<"°)"<<endl;
	cout << "Die Position (X/Y) des Saugroboters lautet: "<<m_X<<"m/"<<m_Y<<"m"<<endl<<endl;


	return;
}

CVacubot::~CVacubot()
{
	m_World->show(m_X, m_Y, m_Alpha, m_Diameter=0);
}



main.cpp
code:
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:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
// GIT-Labor
// main.h

////////////////////////////////////////////////////////////////////////////////
// Header-Dateien
#include <iostream>		// Header für die Standard-IO-Objekte (z.B. cout, cin)
#include <stdlib.h>
// TODO: Fügen Sie hier weitere benötigte Header-Dateien ein

using namespace std;	// Erspart den scope vor Objekte der
						// C++-Standard-Bibliothek zu schreiben
						// z.B. statt "std::cout" kann man "cout" schreiben
#include "CVacubot.h"
#include "cleanerbot/World.h"
//#include "CPoint.h"

// Inkludieren Sie die Header-Datei Ihrer Klasse


// Hauptprogramm
// Dient als Testrahmen, von hier aus werden die Klassen aufgerufen
int main (void)
{

	World world;
	CVacubot Saugroboter;

	Saugroboter.setAlignment(90);
	Saugroboter.setMovement(1);
	Saugroboter.print();
	Saugroboter.setAlignment(-60);
	Saugroboter.setMovement(1);
	Saugroboter.print();
	Saugroboter.setWorld;



	return 0;
}


Edit: World.h und World.cpp nach Anforderung entfernt.
Thema: Dynamische Objekte und Attribute
Tommy

Antworten: 14
Hits: 9.710
02.12.2014 17:02 Forum: Softwaretechnik


Die World.h die wir verwenden ist eine ganz andere, als das was Du da oben verlinkt hast.
Die show Methode ist dort auch gegeben:

Zitat:

void World::show
219 (double positionX, double positionY, double angle, double diameter) {
220 stringstream cmd;
221 cmd << "VACUUM CLEANER "
222 << positionX << ","
223 << positionY << ";"
224 << cos(angle) << "," << sin(angle) << ";"
225 << diameter;
226 sendCommand(cmd);
227 }


Und wir sollen diese Methode in "setWorld" aufrufen, sowie in jeder anderen Methode die die Position des Roboters ändert.

Ich bin jetzt soweit, dass ich denke, dass das Attribut "World* m_World" ein Attribut ist, dass "m_World" heisst und zur Klasse "World" gehört.

Was ich immer noch nicht verstehe ist, wie ich dem Attribut m_World die Werte für m_X, m_Y, m_Alpha und m_Diameter übergebe.

Ausserdem verstehe ich nicht wieso in der Methode "setWorld(World* world)" steht und nicht "setWorld(World* m_World)".
Thema: Dynamische Objekte und Attribute
Tommy

Antworten: 14
Hits: 9.710
02.12.2014 13:50 Forum: Softwaretechnik


Der Absatz im Skript über die Übergabe per Pointer hat mir nicht geholfen.
Letztendlich steht da, dass eine Übergabe per reference grundsätzlich vorzuziehen ist, da sie das gleiche macht, aber weniger fehleranfällig ist.

Mir ist einfach nicht klar, wie das Attribut "World* m_World" zu verstehen ist.
Ich habe das in meiner CVacubot.h so implementiert:

Zitat:

#define CVACUBOT_H_

#include "cleanerbot/World.h"
class CVacubot {

private:
double m_Diameter;
double m_X;
double m_Y;
double m_Alpha;
int m_M;
World* m_World;

public:
CVacubot();
~CVacubot();
double getPosition();
double getAlignment();
double setAlignment(double Alpha);
int setMovement(int M);
void print();
void setWorld(World* world);

};


Im .cpp file habe ich dann im Default Konstruktor "m_World=0" gesetzt um es wie in der Aufgabenstellung gefordert mit NULL zu initialisieren.

Bisher sieht meine Methode im .cpp file so aus:

Zitat:

#include <iostream>
#include <stdlib.h>
#define _USE_MATH_DEFINES
#include <cmath>
using namespace std;
#include "CVacubot.h"
#include "cleanerbot/World.h"

CVacubot::CVacubot()
{
m_Diameter=0.4;
m_X=0;
m_Y=0;
m_Alpha=0;
m_M=0;
m_World=0;
}

void CVacubot::setWorld(World* world)
{


m_World->show(m_X, m_Y, m_Alpha, m_Diameter=0.4);

return;
}


Sobald ich die Methode der Klasse World "show(...)" aufrufe stürtzt auch die .exe von meinem Programm ab :-(
Thema: Dynamische Objekte und Attribute
Tommy

Antworten: 14
Hits: 9.710
02.12.2014 12:32 Forum: Softwaretechnik


Vielen Dank für Deine Antwort :-)

Wir sollen erst ein Objekt der Klasse World erzeugen (und es dann verwirrenderweise world nennen) und dann ein Objekt der Klasse CVacubot (So habe ich meine Saugroboterklasse gennannt). Und dann sollen wir das Objekt world der Saugroboterklasse mit der Methode setWorld bekannt machen.
In der main sähe das dann so aus:

int main void()
{
World world;
CVacubot Saugroboter;

Saugroboter.setWorld();

return 0;
}

Jetzt ist es aber so, dass wir ja die Position des Saugroboters mit den vorher geschriebenen Methoden setAlignment und setMovement bewegen können. Also ändern sich die Parameter nicht nur für die Klasse CVacubot, sondern dann ja auch für die Klasse World.

Das bedeutet doch, dass mein Objekt world dynamisch sein muss?

Ich werde erstmal Deinem Hinweis nachgehen und mich mit der Übergabe per Pointer beschäftigen, vielen Dank dafür :-)
Thema: Dynamische Objekte und Attribute
Tommy

Antworten: 14
Hits: 9.710
Dynamische Objekte und Attribute 02.12.2014 00:15 Forum: Softwaretechnik


Meine Frage:
Wir haben in den vergangenen Laboraufgaben einen Saugroboter modelliert.
Er hat die relevanten Attribute:

Ausrichtung m_Alpha
Durchmesser m_Diameter=0.4
X Position m_X
Y Position m_Y
gefahrene Strecke m_M

Aus der Ausrichtung und der Strecke konnten die Positionen X und Y errechnet werden. Dazu haben wir die Methoden setAlignment und setMovement entwickelt mit denen wir die Ausrichtung und die zurückgelegte Strecke eingeben konnten.
Mit der Methode print wurde dann die Position (X/Y) sowie die Ausrichtung Alpha angezeigt.

Nun sollen wir den Saugroboter visualisieren.
Dazu haben wir eine graphische Java Konsole bekommen, die parallel zu Eclipse im hintergrund läuft. Um diese Konsole ansprechen zu können sollten wir eine Klasse "World.h" in unsere Header Datei inkludieren.
Mit der Methode "show(m_X, m_Y, m_Alpha, m_Diameter)" veranlassen wir die Konsole einen Saugroboter an der angegebenen Stelle mit der angegebenen Ausrichtung anzuzeigen.

Und jetzt fangen meine Probleme an, ich zitiere:

"Ergänzen Sie nun in der Implementierung ihrer Saugroboterklasse ein Attribut "World* m_world" mit dem Initialwert NULL. Ergänzen Sie weiter die Methode "void setWorld(World* world)", die dem Attribut den übergebenen Wert zuweist."


Meine Ideen:
Das Asterix bedeutet doch, dass das ein Pointer ist? Also ein Pointer den ich World nenne und der auf m_World zeigt?
Die Werte die ich dem Attribut übergeben will sind doch mein Ausrichtungswinkel und die Strecke, woraus dann noch x und y berechnet werden.
Das müsste ich dann eventuell vorher berechnen und dann die Ergebnisse an m_World übergeben?
Das sind doch mehrere Werte dh m_world müsste dann ein array sein?
Im Grunde will ich die Parameter meiner Saugroboter-Klasse an die World-Klasse übergeben, damit die Konsole diese dann grafisch darstellen kann?
Dafür soll ich ja die Methode "setWorld" schreiben ... wird das dann ein copy Konstruktor? Aber der kann doch nur Werte derselben Klasse kopieren ?

Ich weiss nicht wie dieses Attribut "World* m_world" zu verstehen ist, deswegen hab ich auch eine Ahnung wie ich denn jetzt die Werte daran übergeben kann.
Zeige Beiträge 1 bis 10 von 10 Treffern