OOP Newbie/ std::string' to `double' in return
-
Wie hast du die ganze Zeit gelernt? Weil du solltest dich vielleicht mal mit den Basics der OOP in C++ gründlich befassen. Alles erklären kann man nicht, vieles muss man durch Eigeninitiative erlernen sonst fruchtet das alles gar nicht.
-
#include<iostream> #include<string> using namespace std; class Angestellter { private: string m_Nachname; //Attribute string m_Vorname; double m_Brutto; public: double ZeigBrutto(); //gibt den Wert des Attributs m_Brutto zurück void SetzeBrutto(double neuBrutto); //setzt einen neuen Wert für Brutto von der main aus //in diesem Falle z.B. auf 3000 Angestellter(string nachame, string vorname, double brutto); //Konstruktor der den //Attributen einen Wert zuweist ~Angestellter(); //destruktor noch nicht notwendig }; //______________________________________________________________________________________ double Angestellter::ZeigBrutto() const //diese Methode kann const gesetzt werden, da sie nichts { //verändert return m_Brutto; //diese Methode ermöglicht einen kleinen Zugriff auf das private Attribut //m_Brutto //die Variable Bruttolohn aus der main() kriegt den Wert von m_Brutto zu- //gewiesen, indem wir Bruttolohn = Angesteller1.ZeigBrutto(); schreiben //und Bruttolohn den zurückgegeben Wert von ZeigBrutto() bekommt //der im erste Fall 2000 entspricht und beim 2. aufrufen 3000 } void Angestellter::SetzeBrutto(double neuBrutto) { m_Brutto=neuBrutto; //m_Brutto wird auf 3000 gesetzt } Angestellter::Angestellter(string nachname, string vorname, double brutto) { //dem Konstruktor werden 3 Werte übergeben : Meier, Franz, 2000 m_Nachname = nachname; //m_Nachname = Meier m_Vorname = vorname; //m_Vorname = Franz m_Brutto = brutto; //m_Brutto = 2000 } //man könnte diesen Konstruktor auch folgt schreiben bzw. sollte man /* Angesteller::Angesteller(string nachname, string vorname, double brutto) : m_Nachname(nachname), m_Vorname(vorname), m_Brutto(brutto) {} */ Angestellter::~Angestellter() { //destruktor ist nicht nötig, da nicht mit dem Heap gearbeitet wurde //Heap = Speicher, für den man selbst sorgen muss und aufräumen muss } //_______________________________________________________________________________________ int main() { double Bruttolohn; //Variable in der der Bruttolohn gespeichert wird, von einem Objekt der Klasse //Angesteller //diese Variable kriegt ihren Wert durch die Methode ZeigBrutto() die //einen Wert zurückliefert, nämich das Attribut m_Brutto Angestellter Angestellter1("Meier", "Franz", 2000.0); //ein Objekt von Angesteller wird erstellt //dem Konstruktor werden Werte übergeben //m_Nachmame wird auf Meier gesetzt //m_Vorname wird auf Franz gesetzt //m_Brutto auf 2000 Bruttolohn = Angestellter1.ZeigBrutto(); //Bruttolohn bekommt den Wert der gerade auf 2000 //gesetzt wurde Bruttolohn = m_Brutto cout << "Bruttolohn:" << Bruttolohn <<endl; Angestellter1.SetzeBrutto(3000.0); // m_Brutto wird auf 3000 gesetzt Bruttolohn = Angestellter1.ZeigBrutto(); //Bruttolohn = m_Brutto (3000) cout << "Bruttolohn:" << Bruttolohn <<endl; system ("PAUSE"); //ich würde hier raten <conio.h> zu inkludieren und getch() zu benutzen return 0; }Wenn du jetzt immer noch nichts verstanden hast, würde ich dir raten dir alles nochmal genau aus deinem Buch durchzulesen.
-
wow vielen dank für die antwort!!!
wirklich sehr gut und ausfürhlich erklärt.
trotzdem eine frage. ich habe gelernt, dass man nur mit den methoden, die in der klasse unter public zu finden sind auf die attribute bzw. membervariablen zugreifen kann.
wenn wir jetzt aber mit folgenden code:
Angestellter::Angestellter(string nachname, string vorname, double brutto) { //dem Konstruktor werden 3 Werte übergeben : Meier, Franz, 2000 m_Nachname = nachname; //m_Nachname = Meier m_Vorname = vorname; //m_Vorname = Franz m_Brutto = brutto; //m_Brutto = 2000 }auf die attritbute zugreifen mache ich dies nicht über eine methode sondern über den konstruktor. wie ist das zu verstehen?
mir ist schon klar, dass der nachename, vorname und das brutto gehalt innerhalb der main funktion an den konstruktür übergeben werden (ich meine den konstruktor der innerhalb der Methodendefinition steht) bzw. man sagt dort, dass der nachname gleich den wert haben soll wie m_nachname. aber wo ist bitteschon die mehthode innerhalb der klassendeklaration genauer gesagt unter public die sagt, dass nachname=m_nachnemane ist?weil ganz genau genommen existiert dort keine methode sondern "nur" ein
konstruktor. und zwar dieser hier:Angestellter(string nachname, string vorname, double brutto);ich bin aber der meinung, dass die übergabe der werte auch über eine methode laufen muss oder wie kann es sein, dass plötzlich die attribute durch den konstruktor verändert werden können?
danke!
-
Ein Konstruktor IST eine Methode. Es ist einfach eine Methode die ausgeführt wird, selbst wenn man es nicht will, wenn man ein Objekt der Klasse erstellt.
-
mittlerweile habe ich hoffentlich alles verstanden aber mich würde mal interessieren wo genau in meinen prog instanzen sind?
außerdem wäre es toll folgende bezeichnungen zu wissen:
hier ist einmal der konstruktor zu sehen der sich innerhalb der klasse im bereich publich befindet:
Angestellter(string nachname, string vorname, double brutto); ~Angestellter();// Desktruktoraber wie bezeichnet man folgenden ausdruck der sich bereits in der methodendefinition befindet:
Angestellter::Angestellter(string nachname, string vorname, double brutto) { m_Nachname = nachname; m_Vorname = vorname; m_Brutto = brutto; }ist dies auch eon konstruktor??!???
und dann wäre es toll zu wissen welche konstruktor ausgeführt wird bzw aufgerufen wird wenn ein objekt der klasse angestellter erstellt wird. denn anscheinend taucht der konstruktor ja zweimal auf.
jetzt gibt es bestimmt ärger

-
Ärger gibts nicht wirklich
ja, das ist auch ein Konstruktorwelcher aufgerufen wird, ist, wie man das Objekt seiner Klasse erstellt:
class Test { Test(); // Standardkonstruktor (parameterloser Konstruktor) Test(int zahl); // auch ein Konstruktor ~Test(); // Destruktor }wenn ich jetzt ein Objekt der Klasse Test erstelle, dann wird hier:
Test myObject;der erste Konstruktor aufgerufen, weil ich beim Erstellen des Objekts keinen Parameter mit übergeben habe
wenn ich jetzt aber sowas mache:
Test myObject(10);dann wird da der zweite Konstruktor aufgerufen, weil ich einen Parameter übergeben, der ein int (eine Zahl) ist und dadurch eben zum zweiten Konstruktor meiner Klasse passt
das würde aber zu nem Fehler führen:
Test myObject("hallo");weil ich keinen Konstruktor habe, der einen string entgegennimmt
das ist natürlich auch falsch:
Test myObject(10, 10);weil es keinen Konstruktor mit 2 Parameter gibt
eine Instanz deiner Klasse in deinem Programm ist hier:
Angestellter Angestellter1("Meier", "Franz", 2000.0);da erstellst du ein Objekt (eine Instanz wenn man so will) von deiner Klasse
ich hoffe, man konnte verstehen, was ich hier will

-
Nein der Konstruktor existiert nicht 2 Mal. Innerhalb deiner Klasse deklariest du nur die Attribute und deine Methoden. Erst untendrunter definierst du sie. In deiner Klasse schreibst du was dein Konstruktor für Parameter entgegen nimmt, dann unten drunter schreibst du was dein Konstruktor macht.
Deine Klasse könnte auch so aussehen.#include <iostream> class Angesteller { private: std::string m_Nachname; std::string m_Vorname; double m_Brutto; public: Angesteller(std::string nachname, std::string vorname, double brutto) : m_Nachname(nachname), m_Vorname(vorname), m_Brutto(brutto) {} double Zeigbrutto() const { return m_Brutto; } void SetzeBrutto(double neu_brutto) { m_Brutto = neu_brutto; } ... }; int main() { ... }Und wie du siehst sind ist die Funktionalität der Methoden schon IN der Klasse geschrieben und nicht außerhalb mit
double Angesteller::ZeigBrutto() { ... }
-
Nein der Konstruktor existiert nicht 2 Mal. Innerhalb deiner Klasse deklariest du nur die Attribute und deine Methoden. Erst untendrunter definierst du sie. In deiner Klasse schreibst du was dein Konstruktor für Parameter entgegen nimmt, dann unten drunter schreibst du was dein Konstruktor macht.
Deine Klasse könnte auch so aussehen.#include <iostream> class Angesteller { private: std::string m_Nachname; std::string m_Vorname; double m_Brutto; public: Angesteller(std::string nachname, std::string vorname, double brutto) : m_Nachname(nachname), m_Vorname(vorname), m_Brutto(brutto) {} double Zeigbrutto() const { return m_Brutto; } void SetzeBrutto(double neu_brutto) { m_Brutto = neu_brutto; } ... }; int main() { ... }Und wie du siehst sind ist die Funktionalität der Methoden schon IN der Klasse geschrieben und nicht außerhalb mit
double Angesteller::ZeigBrutto() { ... }
-
okay jau so stelle ich mir das auch vor!!!
aber warum existiert denn bitte die möglichkeit beides extra aufzuteilen. damit meine ich warum wird in einen basic buch die klasse extra geschrieben und die methodendefinition.
hat das ein vorteil? naja auch nicht so wichtig

_______________________________________________________________________________meine fragen hören einfach nicht auf. ich möchte alles ganz genau wissen deswegen frage ich so oft nach.
in meine buch steht unter anderem auch, dass nur die methoden in public die attribute verändern dürfen bzw. durch die methoden hat man zugriff auf die atribute!
wenn ich jetzt aber mal weiter spinne weißt mein programm im folgenden abschnitt
den attributen werte zu. das dürfe ja eigentlich nicht funktieren weil dies ja nur über die methoden geht und die methoden stehen im public bereich.Angestellter::Angestellter(string nachname, string vorname, double brutto) { m_Nachname = nachname; m_Vorname = vorname; m_Brutto = brutto; }wenn wir jetzt aber neu definieren und behaupten alles sind methoden, wie wir dies ja bereits bei den konstruktoren gemacht haben würde es ja passen.

aber mein buch sagt mir nur die methoden in public können die attribute verändern.
nächste frage was heißt verändern? lesezugriff oder voll\schreibzugriff??
danke
-
hab enoch einmal eine theorie die ich von dir bestätigt haben möchte

wenn folgendes in der main aufgerufen wird
nachname = Angestellter1.ZeigName();passiert aus meiner sicht folgendes:
1. das porgramm springt in die klasse und zwar in den bereich public.
dort findet das porgramm dann die entsprechende methode.
(anscheinend werden aber keine werte übergeben wie es beim konstruktor
ist,oder?)public: string ZeigName();2. das programm springt in die methodendefinnition und findet dort
selbstverständlich die passende "methode oder das gegenstück"
(oder wie man das nennen möchte). dort ist hinterlegt das
m_Nachname ausgegeben werden soll und das die variabel den wert string hat.
(schon komisch da der variablen typ ja bereits in der klasse unter public
festgelegt wurde ,oder?)string Angestellter::ZeigName() { return m_Nachname; }3. das programm springt wieder in die klasse und zwar in den bereich private und
holt sich de entprechenden wert.class Angestellter // Name der Klasse { private: string m_Nachname; // Attribute der Klasse Angestelltersimmt das so???? und wird beim zweiten schritt wirklich nichts übergeben? es steht ja auch nicht in den klammern?!
-
Ja, korrekt, alles richtig was du gesagt hast.
-
Ich glaub du solltest dir lieber den OOP Bereich deines Buches nochmal durchlesen. Ein Konstruktor IST eine Methode, wieso soll er also kein Zugriff auf die Membervariablen haben.
Zu deinem Methodenaufruf :in main() -> Aufruf der Methode ZeigName() -> in die passende Methode des Objekts wird gesprungen -> die Methode hat Zugriff auf die gesamte Klasse -> sie gibt den Nachnamen zurück -> zurück zur main() -> ...
Und wieso soll nicht die Möglichkeit bestehen die Methodenfunktion schon in die Klasse zuschreiben UND sie aber auch in eine .cpp Datei zu schreiben ? Kann ich dich genau so fragen "Wieso können wir durch Nase UND Mund atmen ?". Es geht einfach und das ist auch gut so. C++ ist vielseitig. By the way, Methoden können auch im private Bereich stehen und die Membervariablen in dem public Bereich.
Aber aufgepasst, sowas würde z.B. nicht gehen#include <iostream> class Test { private: Test() { std::cout << "Test"; } }; int main() { Test test; }
-
meine güte wir reden aneinander vorbei.
der konstruktor hat zugriff auf die attribute, dass ist mir klar.
aber damit der konstruktor zugriff hat benötigt er ja das gegenstück, oder?
einmalbenötigt man den konstruktor
Angestellter(string nachname, string vorname, double brutto);und das passenden gegenstück
Angestellter::Angestellter(string nachname, string vorname, double brutto) { m_Nachname = nachname; m_Vorname = vorname; m_Brutto = brutto;und eigentlich hat nur das gegenstück zugriff auf die atribute?
außerdem wäre es sehr, sehr freundlich von dir wenn du mir meine fragen aus den vorherigen post noch beantworten könntest.
habe dort insgesamt 3 schritte wie ich mir die "verbinung zwischen main und der klasse vorstelle. am liebste wäre es mir wenn du dort direkt kommentare abgeben könntest.
sehe ich das richtig, dass nur die methoden in verbindung mit den "gegenstück" (ich hoffe du weißt jetzt was ich mit gegenstück meine) zugriff auf die attribute haben? mit zugriff meine ich einmal lesezugriff und einmal schreibzugriff
oder anderes gesagt wenn man veruscht ohne methode auf die private daten zuzugreifen erhält man vom compiler die fehlermeldung, dass die variable nicht deklariert ist, korrekt?
DANKE!
-
Mein guter FireFighter hatte dir doch eine Antwort daraufgegeben. Außerdem, es gibt kein Gegenstück, das ist das ein und das selbe. In der Klasse wird es DEKLARIERT und untendrunter DEFINIERT. Das ist das selbe wie :
int foobar; //Deklaration foobar = 55; //Definition //oder int foobar_funktion(int); int foobar_funktion(int blub) { ... }
-
okay, okay dein kollge sagt aber alles in ordnung und du hast einen anderen weg vorgegen.
außerdem hat der kollege noch nicht meine zischenfragen beantwortet

-
Sag mal hast du kein ICQ
... 252644818
-
So pass auf. In einer Klasse gibt es, solange wie du ihn alleine implementiert hast, immer einen Konstruktor.Dieser Konstruktor wird bei jeder Geburt eines Objektes aufgerufen, besser gesagt der Konstruktor ist die Hebame f[r dein Objekt, ohne Konstruktor->kein Objekt. Jeder Konstruktor hat generell immer Zugriff auf die Member, genauso wie jede Funktion in deiner Klasse Zugriff auf alle Member hat.Man kann in C++ die Implementation von der Deklaration trennen, das ist dein angegebenes "Gegenstück". Wobei es an sich nichts mit Gegenstück zu tuen hat, denn das Gegenstück des Ctor ist deer Destruktor. Was du gmit Gegenstück bezeichnet hast, ist nichts weiter als die ausgelagerte Implementation des Ctor. Also wo liegt jetzt das Problem?
-
zuzu schrieb:
und das passenden gegenstück
Angestellter::Angestellter(string nachname, string vorname, double brutto) { m_Nachname = nachname; m_Vorname = vorname; m_Brutto = brutto;Noch als Ergänzung:
Besser wäre es zudem die Initialisierungsliste zu verwenden, und zumindestens Objekte per const Referenz zu übergeben.Begründung:
Mit dem obigen Code wird für jeden Aufruf des Konstruktors (sofern der Compiler es nicht wegoptimieren kann) erst einmal alle Werte kopiert (Stichword: Call-By-Value), die Membervariablen mit dem Standardkonstruktor initialisiert, und anschließend eine Zuweisung gemacht. Unnötige Kopien sollte man zumindestens bei Objekten vermeiden, und unnötige Zuweisungen finde ich auch nicht besonders (Man soll zwar nicht vorträglich optimieren, aber vorträglich unnötig Performance zu verbrauchen halte ich auch nicht für sonderlich gut).
Die Initialisierungsliste kann bei allen Konstruktoren verwendet werden (und nur dort), erlaubt zudem auch das setzen von Konstanten und Referenzen.
Angestellter::Angestellter( string const & nachname, // Zumindestens bei Objekten statt "Call-By-Value" string const & vorname, // lieber mit konstanter Referenz arbeiten double brutto) : m_Nachname(nachname), // Initialisierungsliste. Hier werden die Member m_Vorname(vorname), // nun wirklich initialisiert, im Konstruktorrumpf m_Brutto(brutto) // fände eine nachträgliche Zuweisung statt { }cu André
-
noch einmal vielen dank an "FreakY<3Cpp"
ich glaube ohne seine hilfe hätte ich ds nicht verstanden
danke!!! :xmas1: :xmas2: