Erstes OOP Projekt - Erschaffung einer Instanz namens Person - gelöst
-
Hallo und guten Abend liebe Gemeinde.
Ich habe mich einmal in der Klassenprogrammierung probiert.
Folgenden Quellcode habe ich aufgesetzt:
In der Header-Datei „Deklaration.h“ habe ich folgendes geschrieben:class Person { public: std::string Vorname; std::string Nachname; double Alter; double Gewicht; double Größe; std::string Augenfarbe; std::string Haarfarbe; };In der CPP – Datei habe ich folgendes geschrieben:
#include <iostream> #include <string> #include "Deklaration.h" using namespace std; int main() { cout << "\tErste bewusste Klassendeklaration!\n"; cout << "\n"; Person Passant; cout << "Geben Sie Ihren Vornamen an!\n"; cin >> Passant.Vorname; cout << "Geben Sie Ihren Nachnamen an!\n"; cin >> Passant.Nachname; cout << "Geben Sie Ihr Alter an!\n"; cin >> Passant.Alter; cout << "Geben Sie Ihr Gewicht an!\n"; cin >> Passant.Gewicht; cout << "Geben Sie Ihre Augenfarbe an!\n"; cin >> Passant.Augenfarbe; cout << "Geben Sie Ihre Haarfarbe an!\n"; cin >> Passant.Haarfarbe; cout << "Geben Sie Ihre Groesse an!\n"; cin >> Passant.Größe; cout << "\n"; cout << "Das haben Sie angegeben:\n"; cout << "\n"; cout << "Vorname: " << Passant.Vorname << "\n"; cout << "Nachname: " << Passant.Nachname << "\n"; cout << "Alter: " << Passant.Alter << "\n"; cout << "Gewicht: " << Passant.Gewicht << "\n"; cout << "Augenfarbe: " << Passant.Augenfarbe << "\n"; cout << "Haarfarbe: " << Passant.Haarfarbe << "\n"; cout << "Groesse: " << Passant.Größe << "\n"; return 0; }Nun wollte ich die Variablen(=Daten=Attribute), die ich als
publicdeklariert habe, alsprivatedeklarieren und über Elementfunktionen(=Methoden) auf die Attribute zugreifen.
Hier noch einmal die Syntax für eine Klassendeklaration:class Klassenname { public: Typ elementfunktion1(); Typ elementfunktion2(); //und weitere private: Typ attribut1; Typ attribut2; //weitere };Ich muss zugeben, dass ich momentan keinen Plan habe, wie ich einen Konstruktor, Destruktor und Elementfunktionen erstellen muss, damit ich eben auf die Attribute wie Haarfarbe, Augenfarbe, usw. zugreifen kann.
Wie würdet ihr das machen? Hätte einer von euch einen konstruktiven Vorschlag bzw. Lösungsansatz??
Vielen Dank für die Antworten im Voraus.
Gruß
MaxEdit:
Auf http://www.cplusplus.com/reference/ wird folgendes Beispiel aufgeführt:
// classes example #include <iostream> using namespace std; class CRectangle { int x, y; public: void set_values (int,int); int area () {return (x*y);} }; void CRectangle::set_values (int a, int b) { x = a; y = b; } int main () { CRectangle rect; rect.set_values (3,4); cout << "area: " << rect.area(); return 0; }Hier nun meine Fragen:
1.)Kann es sein, dass man nicht immer einen Konstruktor und einen Destruktor benötigt?
2.)x und y sindprivate. Kann man denn mit einer Funktion, im Beispiel von C++ Reference, mitint area () {return (x*y);}ganz einfach auf die Attribute x und y zugreifen?
3.)Was hat der Datentypvoidhier für eine Bedeutung? Verstehe ich das richtig, dass die Funktionvoid set_valuesnichts zurück gibt??
4.)Warum werden x und y als private deklariert, wenn so wieso a und b verwendet werden??Gruß
Max
-
1.- ja, das stimmt. Du brauchst einen Konstruktor um ein Objekt zu erschaffen und initial in einen gültigen Zustand zu befördern. Einen Destruktor brauchst du nur in Sonderfällen, siehe dazu die Regel der Großen Drei.
2.- ja kannst, dafür sind diese Memberfunktionen (auch Methoden genannt) da
3.- Ja. Die setzt nur die Internas auf den übergebenen Wert
4.- Werden sie nicht. Es gibt das Konzept der Kapselung, such da mal nach.
-
Skym0sh0 schrieb:
..., siehe dazu die Regel der Großen Drei.
Was sind denn die Großen Drei??
-
...
-
Mein Software Engineering Prof würde mich töten
Deklariere Attribute private und verwende Getter- und Setter-MethodenLG, freakC++
-
...
-
Da fällt mir eine Frage ein, die ich schon immer mal stellen wollte:
Sämtliche Member sind bei mir privat und werden über Getter/Setter erreichbar. Bei Werten, bei denen es keine spezielle Prüfung gibt, ist da eine inline-Funktion genauso schnell, wie als wenn die Member public wären? Ich denke mal schon, oder?
-
freakC++ schrieb:
und verwende Getter- und Setter-Methoden
Dafür würde dich der ein oder andere auch tötgen.

-
Aber nur, wenn er keine Ahnung von Software Engineering hat.
-
Nathan: Eher nicht, der Compiler optimiert das schon.
freakC++: Da würde ich mich nicht so weit aus dem Fenster lehnen.
-
freakC++ schrieb:
Aber nur, wenn er keine Ahnung von Software Engineering hat.
struct Number { int value; };vs.
class Number { int value; public: int getValue() const { return value; } void setValue(int newValue) { value = newValue; } };
-
out schrieb:
freakC++ schrieb:
und verwende Getter- und Setter-Methoden
Dafür würde dich der ein oder andere auch tötgen.

Der Trick ist, dass man nur Getter und Setter für die Member anbietet, auf die man von aussen auch Zugriff haben soll. Alles andere soll ja aber die "normalen" Methoden gehen. Der Nutzer soll ja auch keine Ahnung und auch kein Interesse an deiner Implementierung haben, wenn doch ist er schon falsch dran.
(Regel: Programmiere gegen Interfaces und nicht gegen Implementierungen)
-
Ethon schrieb:
freakC++ schrieb:
Aber nur, wenn er keine Ahnung von Software Engineering hat.
struct Number { int value; };vs.
class Number { int value; public: int getValue() const { return value; } void setValue(int newValue) { value = newValue; } };Solange es in C++ keine Property-Schreibweise gibt, ziehe ich in der Regel (Ausnahme s.u.) letzteres aus mehreren Gründen trotz des Overheads vor:
1. Man kann ohne den restlichen Code umschreiben zu müssen auch noch nachträglich Bereichsprüfungen oder andere nötige Logik durchführen.
2. Man kann die Zugriffe regeln (z.B. auf Setter verzichten, oder diese nur für abgeleitete Objekte freigeben - auch hier ziehe ich wegen Punkt 1. diese Schreibweise vor), und für gegenseitig abhängige Werte auch ein Interface erzwingen in dem diese als Gesamtheit gesetzt werden (Dann halt nicht mehr unbedingt über einen "normalen" Setter mit einem Parameter).Bei Objekten die ausschließlich dem Datenaustausch dienen und keinerlei Logik aufweisen, verzichte ich aber auf Setter/Getter.
-
silent_max schrieb:
class Person { public: //... double Alter; double Gewicht; double Größe; //... };Mehrere kleinere Anmerkungen:
1. Bist du sicher das Alter ein double sein soll? Ich würde hier eher von einem Ganzzahltyp ausgehen (je nach Definition der Einheit gilt dies auch für Gewicht und Größe). Dir ist hoffentlich bewusst das du double-Werte nicht ohne ein delta sinnvoll vergleichen kannst. Wann möglich ziehe ich daher immer Integerwerte den Gleitkommawerten vor.2. Nur um mal etwas aus der Praxis zu reden: Wenn es um ein echtes Programm geht, würde man in der Regel das Alter als berechneten Wert ansetzen, und statt dessen sein Geburtsdatum hinterlegen (Heute mag Max Mustermann 36 sein, in ein paar Tagen aber vielleicht schon 37).
-
Ich lege dem Threadersteller nahe, sich zuerst mit den grundlegenden Dingen in C++ (Datentypen, Funktionen, Operatoren, etc.) auseinanderzusetzen und erst dann OOP lernen. Alles gleichzeitig machen bringt nichts. Damit kommst du nur durcheinander (wie jetzt) und sehr langsam voran.
-
[Rewind] schrieb:
Ich lege dem Threadersteller nahe, sich zuerst mit den grundlegenden Dingen in C++ (Datentypen, Funktionen, Operatoren, etc.) auseinanderzusetzen und erst dann OOP lernen.
OOP ist leider jetzt das aktuelle Thema in seinem Kurs. Max ist daher dazu gezwungen, sich jetzt damit auseinanderzusetzen,
-
daddy_felix schrieb:
OOP ist leider jetzt das aktuelle Thema in seinem Kurs. Max ist daher dazu gezwungen, sich jetzt damit auseinanderzusetzen,
Dann hat unser Max etwas falsch gemacht. Ich kann mir unmöglich vorstellen, dass der Prof in seinem Kurs irgendwelche OOP-Aufgaben aufgibt, ohne vorher void behandelt und erklärt zu haben.
-
Das problem ist ja auch, dass man zwar anfangs sicherlich was über z.B. Gleitkommaungenauigkeit liest, das aber noch nicht einordnen kann und es somit recht flott wieder vergisst. Erst wenn man darüber wieder mal stolpert, erinnert man sich vielleicht und schafft Abhilfe oder sucht nach Alternativen.
Ich finde es eh immer verwerflich, wenn man als Programmieranfänger mit allen Sachen auf einmal zugebombt wird, man kann fast nichts richtig machen (in den Augen eingier hier im Forum).
Lernt man Funktion, wird einem dazu geraten OOP zu nutzen, lernt man OOP kommt direkt Polymorphie, Inheritance und Design-Patterns. Nutzt man auch das wird man angeschnauzt warum man keine generischen Designs mit STL, TMP und Boost nutzt.
Da sollten auch wir etwas Älteren/Erfahreneren mal dran denken...
-
Skym0sh0 schrieb:
Ich finde es eh immer verwerflich, wenn man als Programmieranfänger mit allen Sachen auf einmal zugebombt wird, man kann fast nichts richtig machen (in den Augen eingier hier im Forum).
Ist das eine alggemeine Aussage oder bezieht sich das auf Max? Beim Letzteren würde das nicht stimmen, da unser Bildungssystem noch nicht so schlecht ist, dass alles in der ersten Vorlesungssitzung/Unterrichtsstunde drankommt. Normalerweise hat man eine Woche Zeit um das Gelernte aufzunehmen, zu üben und zu wiederholen. Jemand, der das wirklich lernen will, schaut noch über den Tellerrand hinaus und nimmt sich die zwei Stunden Zeit zusätzlich, um mehr zu machen als in der Aufgabe verlangt ist. Das ist aber alles schon ein anderes Thema. Fakt ist für mich, dass der Threadersteller zuerst ein paar Sachen nachholen muss, wenn er das lernen will.
-
Nein, das bezieht sich nicht auf Max oder indirekt auf ihn, sondern auf generell Anfänger.
Es geht mir eher um die Informationsflut, die hier im Forum auf Anfänger einprasselt und abverlangt wird.
Als ich damals angefangen habe mit C++ (vorher kannte ich ein klein bisschen Java), waren Arrays auch nur das was ich heute als C-Arrays kenne. An Vector und Konsorten hab ich damals nichtmals mein Zunkunfts-Ich denken lassen. Aber wenn hier im Forum jemand eine Frage stellt wird er sofort (unabhängig von seinem Skill) an den vector verwiesen. Das Ganze gibt es natürlich auch mit Zeigern und Smart-Pointern und auch im Klassendesign Bereich.
C++ ist eine Sprache, die viele Eigenarten hat (positive wie negative) anhand derer man sich ziemlich verrennen kann im Entwicklungs- und Lernzyklus.
Ich denke, es muss nicht immer die perfekte C++-Lösung verlangt oder dann gepostet werden, sondern eventuell auch eine die etwas C-lastiger ist.Denn absprechen kann das keiner, Fehlermeldungen was Templates angeht sind alles andere als gut zu verstehen (jedenfalls anfangs).