Die Klasse Rechteck (C++) < C/C++ < Programmiersprachen < Praxis < Informatik < Vorhilfe
|
Status: |
(Frage) beantwortet | Datum: | 13:15 Sa 27.04.2013 | Autor: | Mija |
Aufgabe | Schreiben Sie ein C++-Programm, in dem eine Klasse Rechteck implementiert und getestet wird. Diese Klasse bildet ein Recheck im kartesischen Koordinatensystem mittels zweier Punkte ab: ein Punkt, der die untere linke Ecke, und ein Punkt, der die obere rechte Ecke markiert. Die Seiten des Rechtecks werden durch Geraden, die parallel zu den Achsen verlaufen, gebildet. Ein Rechteck wird also durch zwei Punkte mit Koordinaten (x,y) bestimmt. Gibt es nur einen Punkt, so wird dieser Punkt als die obere rechte Ecke betrachtet, die linke untere Ecke ist dann der Ursprung. Die Definition der Klasse in der Datei rechteck.h sowie ein Testprogramm rechteck_main.cpp finden Sie in moodle.
a) Implementieren Sie die Methoden und globalen Funktionen aus der Header-Datei.
b) Beachten Sie, dass die Klasse mehrere Konstruktoren besitzt.
c) Der Standardkonstruktor setzt die beiden Punkte an den Ursprung.
d) Die Methode flaeche() berechnet die Fläche des Rechtecks.
e) Die Methode diagonale() berechnet die Länge der Diagonale des Rechtecks.
f) Die Methode istQuadrat() prüft, ob das Rechteck ein Quadrat ist.
g) Die Methode getMittelpunkt() berechnet und liefert den Mittelpunkt des Rechtecks zurück.
h) Die Methode ausgabe() soll die beiden Eckpunkte des Rechtecks sowie seine Fläche, Diagonale und eine Information darüber, ob das Rechteck ein Quadrat ist, ausgeben.
1: | /* rechteck.h */
| 2: |
| 3: | #ifndef RECHTECK_H
| 4: | #define RECHTECK_H
| 5: |
| 6: | struct Punkt {
| 7: | double x;
| 8: | double y;
| 9: | };
| 10: |
| 11: | class Rechteck {
| 12: | private:
| 13: | Punkt untenLinks;
| 14: | Punkt obenRechts;
| 15: | bool istQuadrat();
| 16: |
| 17: | public:
| 18: | // Konstruktoren
| 19: | Rechteck();
| 20: | Rechteck(double xUnLi, double yUnLi, double xObRe, double yObRe);
| 21: | Rechteck(Punkt unLi, Punkt obRe);
| 22: | Rechteck(Punkt p);
| 23: |
| 24: | // Getter- und Setter-Methoden
| 25: | void setUntenLinks(Punkt p);
| 26: | void setObenRechts(Punkt p);
| 27: | Punkt getUntenLinks();
| 28: | Punkt getObenRechts();
| 29: |
| 30: | // weitere Methoden
| 31: | double flaeche() ;
| 32: | double diagonale();
| 33: |
| 34: | Punkt getMittelpunkt();
| 35: | void ausgabe();
| 36: | };
| 37: |
| 38: | void eingabePunkt(Punkt& p);
| 39: | void ausgabePunkt(Punkt& p);
| 40: |
| 41: | #endif // RECHTECK_H |
1: | /* rechteck_main.cpp */
| 2: |
| 3: | #include <iostream>
| 4: | #include "rechteck.h"
| 5: |
| 6: | using namespace std;
| 7: |
| 8: | int main(void) {
| 9: |
| 10: | Punkt p1 = { 1.7, 3.4 };
| 11: | Punkt p2 = { 5.9, 7.6 };
| 12: | Rechteck r1;
| 13: | r1.setUntenLinks(p1);
| 14: | r1.setObenRechts(p2);
| 15: | r1.ausgabe();
| 16: | cout << "----------------------------------------------------------------------------" << endl;
| 17: |
| 18: | eingabePunkt(p1);
| 19: | eingabePunkt(p2);
| 20: | Rechteck r2(p1, p2);
| 21: | r2.ausgabe();
| 22: | cout << "----------------------------------------------------------------------------"<< endl;
| 23: |
| 24: | Rechteck r3(-1.2, -3.4, 5.6, 7.8);
| 25: | r3.ausgabe();
| 26: | ausgabePunkt( r3.getMittelpunkt() );
| 27: | cout << endl;
| 28: | cout << "----------------------------------------------------------------------------"<< endl;
| 29: |
| 30: | Punkt p;
| 31: | eingabePunkt(p);
| 32: | Rechteck r4(p);
| 33: | r4.ausgabe();
| 34: | ausgabePunkt( r4.getUntenLinks() );
| 35: | cout << endl;
| 36: | ausgabePunkt( r4.getMittelpunkt() );
| 37: | cout << endl;
| 38: | ausgabePunkt( r4.getObenRechts()) ;
| 39: | cout << endl;
| 40: | cout <<"----------------------------------------------------------------------------"<< endl;
| 41: | return 0;
| 42: | } | |
Hallo, ich habe versucht die obenstehende Aufgabe zu lösen.
Wie kann ich in meine Funktionen einbringen, dass die Klasse Rechteck mehrere Konstruktoren hat?
Wegen dieser Frage ist mir noch folgendes unklar: Was muss ich in der rechteck_main.cpp bei ausgabePunkt( r4.getMittelpunkt() ); in die Klammern für getMittelpunkt schreiben? (Zeile 42 in meinem rechteck_main.cpp - Code)
Ich übergebe doch eigentlich vier double-Werte in diese Funktion. Aber hier ist nur ein Punkt p gegeben.
Außerdem habe ich das Problem, dass meine boolesche Funktion istQuadrat() bisher immer nur false zurückgibt (zumindest wird immer eine 0 ausgegeben). Wo ist da mein Fehler? (Zeile 112 in rechteck.cpp)
Ich würde mich sehr freuen, wenn mir jemand weiterhelfen könnte!
Hier sind meine Codes:
1: | /* rechteck.h */
| 2: |
| 3: | #ifndef RECHTECK_H
| 4: | #define RECHTECK_H
| 5: |
| 6: | struct Punkt {
| 7: | double x;
| 8: | double y;
| 9: | };
| 10: |
| 11: | class Rechteck {
| 12: | private:
| 13: | Punkt untenLinks;
| 14: | Punkt obenRechts;
| 15: | bool istQuadrat(double, double, double, double);
| 16: |
| 17: | public:
| 18: | // Konstruktoren
| 19: | Rechteck();
| 20: | Rechteck(double xUnLi, double yUnLi, double xObRe, double yObRe);
| 21: | Rechteck(Punkt unLi, Punkt obRe);
| 22: | Rechteck(Punkt p);
| 23: |
| 24: | // Getter- und Setter-Methoden
| 25: | void setUntenLinks(Punkt p);
| 26: | void setObenRechts(Punkt p);
| 27: | Punkt getUntenLinks();
| 28: | Punkt getObenRechts();
| 29: |
| 30: | // weitere Methoden
| 31: | double flaeche(double, double, double, double) ;
| 32: | double diagonale(double, double, double, double);
| 33: |
| 34: | Punkt getMittelpunkt(double, double, double, double);
| 35: | void ausgabe();
| 36: | };
| 37: |
| 38: | void eingabePunkt(Punkt& p);
| 39: | void ausgabePunkt(Punkt& p);
| 40: |
| 41: | #endif // RECHTECK_H
|
1: | /* rechteck.cpp */
| 2: |
| 3: | #include <iostream>
| 4: | #include <math.h>
| 5: | #include "rechteck.h"
| 6: |
| 7: | using namespace std;
| 8: |
| 9: | // Definition der Konstruktoren
| 10: |
| 11: | //Standardkonstruktor
| 12: | Rechteck::Rechteck()
| 13: | {
| 14: | //unten links auf 0 setzen
| 15: | struct Punkt pUnLi;
| 16: | pUnLi.x=0;
| 17: | pUnLi.y=0;
| 18: | //oben rechts aus 0 setzen
| 19: | struct Punkt pObRe;
| 20: | pObRe.x=0;
| 21: | pObRe.y=0;
| 22: | }
| 23: |
| 24: | //Konstruktoren mit Parametern
| 25: |
| 26: | Rechteck::Rechteck(double xUnLi, double yUnLi, double xObRe, double yObRe)
| 27: | {
| 28: | //unten links
| 29: | struct Punkt pUnLi;
| 30: | pUnLi.x = xUnLi;
| 31: | pUnLi.y = yUnLi;
| 32: | setUntenLinks(pUnLi);
| 33: | //oben rechts
| 34: | struct Punkt pObRe;
| 35: | pObRe.x = xObRe;
| 36: | pObRe.y = yObRe;
| 37: | setObenRechts(pObRe);
| 38: | }
| 39: |
| 40: | Rechteck::Rechteck(Punkt unLi, Punkt obRe)
| 41: | {
| 42: | setUntenLinks(unLi);
| 43: | setObenRechts(obRe);
| 44: | }
| 45: |
| 46: | Rechteck::Rechteck(Punkt p)
| 47: | {
| 48: | //unten links auf Ursprung setzen, da nur ein Punkt gegeben ist
| 49: | struct Punkt pUnLi;
| 50: | pUnLi.x = 0;
| 51: | pUnLi.y = 0;
| 52: | setUntenLinks(pUnLi);
| 53: | //oben rechts
| 54: | struct Punkt pObRe;
| 55: | pObRe.x = p.x;
| 56: | pObRe.y = p.y;
| 57: | setObenRechts(pObRe);
| 58: | }
| 59: |
| 60: |
| 61: | //Implementierung der Methoden
| 62: |
| 63: |
| 64: | // Getter- und Setter-Methoden
| 65: |
| 66: | void Rechteck::setUntenLinks(Punkt p)
| 67: | {
| 68: | untenLinks = p;
| 69: | }
| 70: |
| 71: | void Rechteck::setObenRechts(Punkt p)
| 72: | {
| 73: | obenRechts = p;
| 74: | }
| 75: |
| 76: | Punkt Rechteck::getUntenLinks()
| 77: | {
| 78: | return untenLinks;
| 79: | }
| 80: |
| 81: | Punkt Rechteck::getObenRechts()
| 82: | {
| 83: | return obenRechts;
| 84: | }
| 85: |
| 86: | //andere Methoden
| 87: |
| 88: | double Rechteck::flaeche(double xUnLi, double yUnLi, double xObRe, double yObRe)
| 89: | {
| 90: | double a = xObRe - xUnLi;
| 91: | double b = yObRe - yUnLi;
| 92: | return a*b;
| 93: | }
| 94: |
| 95: | double Rechteck::diagonale(double xUnLi, double yUnLi, double xObRe, double yObRe)
| 96: | {
| 97: | double a = xObRe - xUnLi;
| 98: | double b = yObRe - yUnLi;
| 99: | return sqrt(a*a+b*b);
| 100: | }
| 101: |
| 102: | Punkt Rechteck::getMittelpunkt(double xUnLi, double yUnLi, double xObRe, double yObRe)
| 103: | {
| 104: | struct Punkt M;
| 105: | double a = xObRe - xUnLi;
| 106: | double b = yObRe - yUnLi;
| 107: | M.x = xObRe - a/2;
| 108: | M.y = yObRe - b/2;
| 109: | return M;
| 110: | }
| 111: |
| 112: | bool Rechteck::istQuadrat(double xUnLi, double yUnLi, double xObRe, double yObRe)
| 113: | {
| 114: | double a = xObRe - xUnLi;
| 115: | double b = yObRe - yUnLi;
| 116: | if (a==b)
| 117: | return true;
| 118: | else
| 119: | return false;
| 120: | }
| 121: |
| 122: | void Rechteck::ausgabe()
| 123: | {
| 124: | cout << "x-Koordinate fuer unten links: " << untenLinks.x << endl;
| 125: | cout << "y-Koordinate fuer unten links: " << untenLinks.y << endl;
| 126: | cout << "x-Koordinate fuer oben rechts: " << obenRechts.x << endl;
| 127: | cout << "y-Koordinate fuer oben rechts: " << obenRechts.y << endl;
| 128: | cout << "Flaeche: " << flaeche(untenLinks.x, untenLinks.y, obenRechts.x, obenRechts.y) << endl;
| 129: | cout << "Laenge der Diagnonalen: " << diagonale(untenLinks.x, untenLinks.y, obenRechts.x, obenRechts.y) << endl;
| 130: | cout << "Handelt es sich um ein Quadrat (0 fuer nein, 1 fuer ja): " << istQuadrat(untenLinks.x, untenLinks.y, obenRechts.x, obenRechts.y) << endl;
| 131: | }
| 132: |
| 133: | void eingabePunkt(Punkt& p)
| 134: | {
| 135: | cout << endl << "Geben Sie die x-Koordinate Ihres Punktes ein: ";
| 136: | cin >> p.x;
| 137: | cout << endl << "Geben Sie die y-Koordinate Ihres Punktes ein: ";
| 138: | cin >> p.y;
| 139: | cout << endl;
| 140: | }
| 141: |
| 142: | void ausgabePunkt(Punkt& p)
| 143: | {
| 144: | cout << "Die x-Koordinate des Punktes lautet: " << p.x << endl;
| 145: | cout << "Die y-Koordinate des Punktes lautet: " << p.y << endl << endl;
| 146: | } |
1: | /* rechteck_main.cpp */
| 2: |
| 3: | #include <iostream>
| 4: | #include "rechteck.h"
| 5: |
| 6: | using namespace std;
| 7: |
| 8: | int main(void) {
| 9: |
| 10: | //Rechteck mit vorgegebenen Punkten, ist Quadrat, Ausgabe: 1.7, 3.4, 5.9, 7.6, 17.67, 5.9397, 1
| 11: | Punkt p1 = { 1.7, 3.4 };
| 12: | Punkt p2 = { 5.9, 7.6 };
| 13: | Rechteck r1;
| 14: | r1.setUntenLinks(p1);
| 15: | r1.setObenRechts(p2);
| 16: | r1.ausgabe();
| 17: | cout << "----------------------------------------------------------------------------" << endl;
| 18: |
| 19: | //Punkte werden selbst vom Benutzer eingegeben
| 20: | eingabePunkt(p1);
| 21: | eingabePunkt(p2);
| 22: | Rechteck r2(p1, p2);
| 23: | r2.ausgabe();
| 24: | cout << "----------------------------------------------------------------------------"<< endl;
| 25: |
| 26: | //Rechteck mit vorgegebenen Punkten, kein Quadrat, Ausgabe: -1.2, -3.4, 5.6, 7.8, 76.16, 13.10, 0, Mittelpunkt: 2.2, 2.2
| 27: | Rechteck r3(-1.2, -3.4, 5.6, 7.8);
| 28: | r3.ausgabe();
| 29: | cout << "Mittelpunkt: ";
| 30: | ausgabePunkt( r3.getMittelpunkt(-1.2, -3.4, 5.6, 7.8) );
| 31: | cout << endl;
| 32: | cout << "----------------------------------------------------------------------------"<< endl;
| 33: |
| 34: | //Punkt oben rechts wird selbst vom Benutzer eingegeben, links unten ist der Ursprung
| 35: | Punkt p;
| 36: | eingabePunkt(p);
| 37: | Rechteck r4(p);
| 38: | r4.ausgabe();
| 39: | cout << "Ausgabe des Ursprungs:" << endl;
| 40: | ausgabePunkt( r4.getUntenLinks() );
| 41: | cout << endl;
| 42: | //ausgabePunkt( r4.getMittelpunkt() ); // was kommt hier in die getMittelpunkt-Klammern??
| 43: | cout << endl;
| 44: | cout << "Ausgabe des Punktes oben rechts:" << endl;
| 45: | ausgabePunkt( r4.getObenRechts()) ;
| 46: | cout << endl;
| 47: | cout <<"----------------------------------------------------------------------------"<< endl;
| 48: | return 0;
| 49: | } |
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 20:37 Sa 27.04.2013 | Autor: | Mija |
Die Frage wegen der Methoden und Konstruktoren hat sich erledigt.
Meine bool-Methode funktioniert nur leider für das erste Beispiel noch nicht. Dort müsste ja eigentlich eine 1 ausgegeben werden, denn es handelt sich um ein Quadrat.
Wenn ich allerdings in den Beispielen, wo ich selbst Punkte eingeben kann, etwas eingebe, so dass es sich um ein Quadrat handelt.. dort wird mir dann ganz brav eine 1 ausgeben.
Wo ist mein Fehler?
Kann mir denn niemand weiterhelfen?
|
|
|
|
|
Hallo!
Dein Problem liegt vermutlich darin, daß du zwei Doubles auf Gleichheit testest. weil sich Fließkommazahlen aus dem Dezimalsystem selten exakt in das Binärsystem übertragen lassen, gibt es da Rundungsfehler. Die sind zwar winzig, machen aber Probleme, wenn du die exakte Gleichheit überprüfen willst. Du kannst das testen:
Füge mal ein cout <<a-b<<endl; ein. Wenn die Seiten wirklich gleich sind, sollte das ja null liefern. Aber vermutlich wirst du dort winzig kleine, aber von 0 verschiedene Zahlen bekommen.
Lösen kannst du das, in dem du dir einen Schwellwert ausdenkst (sagen wir 0.000001), und nun so auf Gleichheit testest:
fabs(a-b)<0.000001
fabs liefert dir den Betrag einer Fließkommazahl.
Aber mal was anderes:
Die Klasse enthält die beiden Member-Variablen untenLinks und obenRechts. (zu sehen in der h-datei)
Darin sollst du die Punkte speichern, die per Konstruktor oder setter-Funktion übergeben werden. Und deine Funktion istQuadrat soll diese Variablen auch benutzen. Die Funktion bekommt keine vier Doubles übergeben!
Grade das macht das objektorientierte Programmieren aus. Du machst einmal ein Rechteck mit Punkten, und kannst es dann fragen, ob es ein Quadrat ist, ohne die Koordinaten nochmal anzugeben. (Das wäre dann C, nicht C++)
Das gilt natürlich auch für all die anderen Funktionen.
|
|
|
|
|
Status: |
(Mitteilung) Reaktion unnötig | Datum: | 00:32 So 28.04.2013 | Autor: | Mija |
Vielen Dank für die Tipps!
|
|
|
|