voldemort Geschrieben 24. März 2011 Teilen Geschrieben 24. März 2011 nabend zusammen, folgende ausgangslage. es exestiert eine klasse CBruch mit Nenner und Zaehler, ebenso drei Methoden setNenner, setZaehler und getDezimal. in meiner main habe ich nun folgendes: CBruch bruch; CBruch bruch1; CBruch bruch2; bruch1.setZaehler(4); bruch1.setNenner(8); bruch2.setZaehler(2); bruch2.setNenner(4); ich weiß also wie ich aus meiner main heraus auf die klasse zugreifen kann. nun möchte ich eine methode zum addieren der zwei brüchen schreiben. meine frage: wie greife ich aus einer methode auf meine main zu um die benötigten werte zu holen..abgesehen davon das die werte ja schon in der klasse vorhanden sind. aber da hab ich ja das problem das ich nicht CBruch CBruch::Addiere (CBruch obj) { Nenner * Nenner; } rechnen kann um auf den gemeinsamen nenner zu kommen. grüße voldemort Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Hexagon Geschrieben 24. März 2011 Teilen Geschrieben 24. März 2011 Moin. Gleich mal zwei Fragen zum Anfang:Wie ist "CBruch" definiert?Schonmal an die Operatoren "+" und "+=" gedacht? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 24. März 2011 Teilen Geschrieben 24. März 2011 Was hindert dich daran, Nenner * obj.Nenner zu rechnen? Oder getNenner() * obj.getNenner()? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 24. März 2011 Teilen Geschrieben 24. März 2011 Was hindert dich daran, Nenner * obj.Nenner zu rechnen? Oder getNenner() * obj.getNenner()? Es geht doch nicht um eine Multiplikation, sondern um die Addition, bei Brüchen ist dabei schon ein Unterschied. Aber die Addition von Brüchen sollte eigentlich recht leicht per Definition gehen Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 24. März 2011 Teilen Geschrieben 24. März 2011 Es geht doch nicht um eine Multiplikation, sondern um die AdditionAuch dafür muss ich die Nenner multiplizieren. Oder zumindest das KGV ermitteln. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 24. März 2011 Teilen Geschrieben 24. März 2011 Ja, aber Die Bruch-Klasse hat doch einen setter für die Werte und sollte dann doch analog einen getter haben...... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 24. März 2011 Teilen Geschrieben 24. März 2011 Ja, aber Die Bruch-Klasse hat doch einen setter für die Werte und sollte dann doch analog einen getter haben...... Ob man in der Methode direkt auf die Member zugreift oder die Getter benutzt, darüber kann man sich sicher streiten. Aber ich habe ja beide Varianten erwähnt Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Der_Lampe Geschrieben 25. März 2011 Teilen Geschrieben 25. März 2011 ist zwar keine besonders schöne Lösung aber schonmal so probiert? CBruch CBruch::Addiere (CBruch bruch1, CBruch bruch2) { ... CBruch erg; erg.setNenner(bruch1.getNenner() * bruch2.getNenner()); erg.setZaehler(bruch1.getZaehler()*bruch2.getNenner()+bruch2.getZaehler()*bruch1.getNenner()); ... } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
voldemort Geschrieben 25. März 2011 Autor Teilen Geschrieben 25. März 2011 so, hab nun ein bisschen gewerkelt. mir war nicht klar das ich in einer methode eine andere methode verwenden kann. danke für die info. habe meine klasse nun mit getNenner und getZaehler erweitert. class CBruch { private: int Zaehler; int Nenner; public: void setZaehler(int z_er); void setNenner(int n_er); CBruch Addiere (CBruch, CBruch); int getNenner (); int getZaehler (); double getKommawert (); }; ich geh ja davon aus das die zwei methoden benötigt werden damit ich die werte in meiner methode Addiere benutzen kann. das problem das ich habe ist aber das ich, wie in der klasse zu sehen, einen fließkommawert des bruches mit hilfe der tastatur eingabe (Zaehler,Nenner) errechnen. damit setze ich ja schon meine werte für Zaehler und Nenner. nun hab ich da ein denk konflikt da ich ja auch ebenfalls in Addiere die werte setzen möchte. wer ist so nett und kann da licht ins dunkel bringen? grüße Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 25. März 2011 Teilen Geschrieben 25. März 2011 ich geh ja davon aus das die zwei methoden benötigt werden damit ich die werte in meiner methode Addiere benutzen kann.Nein, die benötigst du nicht. Du kannst in der Addiere-Methode auch direkt auf Zaehler und Nenner zugreifen. nun hab ich da ein denk konflikt da ich ja auch ebenfalls in Addiere die werte setzen möchte.Ich sehe das Problem nicht. Ist dir klar, dass du in deinem Programm mehrere Objekte deiner Bruch-Klasse erzeugst, und das jedes dieser Objekte seinen eigenen Zähler und Nenner hat? Auch deine Addiere-Methode erzeugt ein neues Bruch-Objekt. Damit kannst du doch machen, was du willst. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
voldemort Geschrieben 25. März 2011 Autor Teilen Geschrieben 25. März 2011 wenn ich das aber nun so programmiere wie Der_Lampe es vorgeschlagen hat benötige ich die methoden doch, da ich ja sonst keine getNenner bzw getZaehler methoden definiert habe. es sie denn du möchtest mich grad in eine andere denkrichtung steuern die einfacher ist. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 25. März 2011 Teilen Geschrieben 25. März 2011 Ich weiß nicht, wie ich es anders beschreiben soll: Du brauchst an dieser Stelle keine get-Methoden. Du kannst direkt auf die private-Member zugreifen. Zeig doch bitte mal, wie du dir die Verwendung deiner Addier-Methode vorstellst. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
voldemort Geschrieben 26. März 2011 Autor Teilen Geschrieben 26. März 2011 meine Addier methode ist basierend auf den lösungsvorschlag von Der_Lampe CBruch CBruch::Addiere (CBruch bruch1, CBruch bruch2) { CBruch obj; obj.setNenner(bruch1.getNenner() * bruch2.getNenner()); obj.setZaehler(bruch1.getZaehler()*bruch2.getNenner()+bruch2.getZaehler()*bruch1.getNenner()); } ich hab es so übernommen, weil es für mich so am logischsten war. aber wenn ich dich richtig versteh geht es einfacher. ich denk mal du denkst an ein Nenner += Nenner und Zaehler += Zaehler. ich häng mal meine main mit rein um zu verdeutlichen was da geschieht. int _tmain(int argc, _TCHAR* argv[]) { CBruch bruch; CBruch bruch1; CBruch bruch2; int z_er, n_er; cout<<"Zaehler eingeben"<<endl; cin>>z_er; bruch.setZaehler (z_er); cout<<"Nenner eingeben"<<endl; cin>>n_er; bruch.setNenner (n_er); cout<<"Fliesskommawert: "<<bruch.getKommawert()<<endl; int a=1,b=2; a+=b; cout<<"in a steht: "<<a<<endl; bruch1.setZaehler(4); bruch1.setNenner(8); bruch2.setZaehler(2); bruch2.setNenner(4); cout<<"Zaehler: "<<bruch.getZaehler()<<endl; //Hier soll die Ausgabe für den cout<<"Nenner: "<<bruch.getNenner()<<endl; // errechneten Bruch sein return 0; } grüße Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 26. März 2011 Teilen Geschrieben 26. März 2011 aber wenn ich dich richtig versteh geht es einfacher. ich denk mal du denkst an ein Nenner += Nenner und Zaehler += Zaehler.Nein, das wäre mathematisch falsch. Ersetze in Addiere (und nur dort) getNenner() durch Nenner und getZaehler() durch Zaehler. Das ist alles. Kürzen solltest du den Bruch danach übrigens auch noch. ich häng mal meine main mit rein um zu verdeutlichen was da geschieht.Da geschieht jedenfalls nichts mit der Addiere-Methode, weil du sie nicht aufrufst. Zeig mal, wie du die aufrufen möchtest. Wie soll Addiere in deinem Code benutzt werden? Dann kann man auch mehr darüber sagen, wie sie aussehen muss. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
voldemort Geschrieben 26. März 2011 Autor Teilen Geschrieben 26. März 2011 (bearbeitet) Nein, das wäre mathematisch falsch. ich dachte ja auch dran das zu machen nachdem ich den gemeinsamen nenner errechnet hab. Ersetze in Addiere (und nur dort) getNenner() durch Nenner und getZaehler() durch Zaehler hab ich gemacht und der code sieht nun so aus CBruch CBruch::Addiere (CBruch bruch1, CBruch bruch2) { CBruch obj; obj.setNenner(bruch1.Nenner * bruch2.Nenner); obj.setZaehler(bruch1.Zaehler*bruch2.Nenner+bruch2.Zaehler*bruch1.Nenner); } zu der main. der code der da steht ist nur ein platzhalter. ehrlich gesagt hab ich mir noch keine gedanken über die ausgabe gemacht. ich geh aber von aus das meine methode Addiere zwei werte zurückgeben muss damit ich in der main mein Zaehler und Nenner aufrufen kann. grüße Bearbeitet 26. März 2011 von voldemort Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 26. März 2011 Teilen Geschrieben 26. März 2011 zu der main. der code der da steht ist nur ein platzhalter. ehrlich gesagt hab ich mir noch keine gedanken über die ausgabe gemacht.Die Ausgabe hat nichts mit der Berechnung zu tun. ich geh aber von aus das meine methode Addiere zwei werte zurückgeben muss damit ich in der main mein Zaehler und Nenner aufrufen kann.Die Denkweise, die dich zu dieser (übrigens falschen) Annahme geführt hat, ist der Grund, warum ich überhaupt nichts von Gettern und Settern halte. Wenn man damit die interne Struktur einer Klasse eins zu eins auf die öffentliche Schnittstelle kopiert, lernt man nicht, dazwischen zu unterscheiden. Du solltest außerhalb der Klasse Bruch überhaupt nicht an Zähler und Nenner denken. Weder solltest du für die Ausgabe eines Bruchs getZaehler und getNenner aufrufen müssen (dafür braucht die Klasse eine Ausgabe-Methode), noch solltest du die Werte über Setter setzen (dafür gibt's Konstruktoren). Deine Addiere-Methode gibt einen Bruch zurück, und das ist auch genau richtig. Ein Bruch kapselt Zähler und Nenner. Wenn du außerhalb der Klasse überall mit Zähler und Nenner hantierst, machst du die Kapselung kaputt. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 26. März 2011 Teilen Geschrieben 26. März 2011 Um das mal zu konkretisieren: Wenn man die Klasse Bruch (was soll der Präfix C da?) ordentlich entwirft, kann main so aussehen: int main() { Bruch b1(4, 8); Bruch b2(2, 4); Bruch b = b1 + b2; cout << b; }[/code]Hier tauchen die Begriffe Zähler und Nenner nur als Bedeutung der Konstruktorparameter auf. So wäre das sauber. Und so ist das auch möglich. Ohne Getter und Setter. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 26. März 2011 Teilen Geschrieben 26. März 2011 Du solltest außerhalb der Klasse Bruch überhaupt nicht an Zähler und Nenner denken. Weder solltest du für die Ausgabe eines Bruchs getZaehler und getNenner aufrufen müssen (dafür braucht die Klasse eine Ausgabe-Methode), noch solltest du die Werte über Setter setzen (dafür gibt's Konstruktoren). Das halte ich in dieser Aussage für bedenklich. Natürlich kann man diskutieren ob ein Bruch als Atom angesehen werden kann, d.h. nachdem das Objekt instantiiert wurde, das es unveränderlich ist. Wäre das nicht der Fall, dann braucht man einen Setter oder man macht in diesem Fall die Eigenschaft öffentlich. Pauschal würde ich nicht sagen, dass ein setter schlecht ist, denn in den meisten Fällen ändert ein setter nicht nur eine Eigenschaft des Objektes, sondern es ändert mehrere, die letztendlich zu einem Zustandswechsel innerhalb des Zustandsdiagramms des Objektes führen. Würde man keine setter verwenden könnte man undefinierte Zustände des Objektes hervorrufen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
voldemort Geschrieben 26. März 2011 Autor Teilen Geschrieben 26. März 2011 der Präfix C steht für class. unser lehrer meint zum sauber programmieren verwendet man dies. normalerweise auch bei methoden dann das m. das problem ist hier das wir uns dran halten müssen was er uns vorgibt. so also auch die set und get methoden. ich mag nicht bezweifeln das es anders sauberer wäre, aber leider kann ich da so nichts dran ändern und muss mich da wohl fügen. also übergebe ich nun einen parameter der main in dem dann Nenner und Zaehler stehen? das müsste dann ja obj sein. wenn dem so wäre stell ich mir aber die frage wie ich es in der main aufrufe soll. obj.Addiere(); geht ja nicht da obj ja ne dekleration in der Addier methode ist. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 26. März 2011 Teilen Geschrieben 26. März 2011 Pauschal würde ich nicht sagen, dass ein setter schlecht ist, denn in den meisten Fällen ändert ein setter nicht nur eine Eigenschaft des Objektes, sondern es ändert mehrere, die letztendlich zu einem Zustandswechsel innerhalb des Zustandsdiagramms des Objektes führen.In den meisten Fällen, die ich gesehen habe, sind Setter Mutatoren für genau eine Membervariable. Das kommt dabei raus, wenn man zu jeder Membervariablen reflexartig Getter und Setter anlegt. Und das sehe ich leider sehr häufig. Würde man keine setter verwenden könnte man undefinierte Zustände des Objektes hervorrufen.Mit dem Verzicht auf Getter und Setter meine ich natürlich nicht, dass man statt dessen die dazugehörigen Member public macht. Das wäre noch schlimmer. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 26. März 2011 Teilen Geschrieben 26. März 2011 der Präfix C steht für class. unser lehrer meint zum sauber programmieren verwendet man dies. normalerweise auch bei methoden dann das m.Au weia. Nur zur Information: Microsoft hat diesen Präfix vor etwa 20 Jahren für die MFC-Klassen benutzt, weil der C++-Compiler damals noch keine Namespaces beherrschte und man so Namenskonflikte vermeiden wollte. Mit "sauber" hat das nichts zu tun. Mach's so, wie es der Dozent will, aber merk dir, dass das eine sehr alte Notlösung für ein inzwischen nicht mehr vorhandenes Problem ist. das problem ist hier das wir uns dran halten müssen was er uns vorgibt. so also auch die set und get methoden. ich mag nicht bezweifeln das es anders sauberer wäre, aber leider kann ich da so nichts dran ändern und muss mich da wohl fügen.getNenner und getZaehler hast du ins Spiel gebracht, wenn ich das richtig sehe. also übergebe ich nun einen parameter der main in dem dann Nenner und Zaehler stehen?Deine Addiere-Funktion gibt einen Bruch zurück. Parameter sind die Dinger, die rein gehen. das müsste dann ja obj sein.Richtig. wenn dem so wäre stell ich mir aber die frage wie ich es in der main aufrufe soll. obj.Addiere(); geht ja nicht da obj ja ne dekleration in der Addier methode ist.Ich glaube, du hast überhaupt noch nicht verstanden, was Funktionen tun. Die Variablen in main und CBruch::Addiere haben nichts miteinander zu tun. Was du in main beim Aufruf von Addiere benutzt, landet in den Parametern bruch1 und bruch2 von Addiere. Dass die dieselben Namen wie Variablen in main haben, bedeutet gar nichts. Die könnten auch ganz anders heißen. Und es wäre für's Verständnis vermutlich auch besser, wenn sie nicht dieselben Namen hätten, damit das deutlich wird. Und wie die Variable heißt, die du als Rückgabewert benutzt, ist auch völlig egal. Du hast zwei Möglichkeiten: Bruch b = CBruch::Addiere(bruch1, bruch2); Bruch b = bruch1.Addiere(bruch2); Das kannst du dir aussuchen. Je nachdem sieht Addiere ein wenig anders aus. Die Version von Der_Lampe entspricht eher der ersten Variante, aber du musst darauf achten, die Methode in der Klassendefinition als static zu deklarieren. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
voldemort Geschrieben 27. März 2011 Autor Teilen Geschrieben 27. März 2011 getNenner und getZaehler hast du ins Spiel gebracht, wenn ich das richtig sehe. korrekt, aber auch nur weil es für mich ne logische konsequenz auf den lösungsansatz war. Ich glaube, du hast überhaupt noch nicht verstanden, was Funktionen tun ich geb zu das ich wieder mal sehr viel durcheinander gebracht habe und werd mir die funtionen noch mal anschauen müssen. hier nun meine Addier methode CBruch CBruch::Addiere (CBruch bruch1, CBruch bruch2) { CBruch obj; obj.setNenner(bruch1.Nenner * bruch2.Nenner); //Nenner gleich bringen obj.setZaehler(bruch1.Zaehler*bruch2.Nenner+bruch2.Zaehler*bruch1.Nenner); return obj; } und nen ausschnitt meiner main bruch1.setZaehler(1); bruch1.setNenner(7); bruch2.setZaehler(2); bruch2.setNenner(5); addition = bruch1.Addiere(bruch1,bruch2); cout<<"Bruch1 :"<<bruch1.getKommawert ()<<endl; cout<<"Bruch2 :"<<bruch2.getKommawert ()<<endl; cout<<"Bruch1 + Bruch2: "<<addition.getKommawert()<<endl; läuft alles. also mal ein danke für die mühen. grüße Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 27. März 2011 Teilen Geschrieben 27. März 2011 läuft alles.Ist aber nicht schön. Addiere ist bei dir nicht static, d.h. du musst diese Methode über ein Bruch-Objekt aufrufen, was du ja auch tust: Du schreibst: bruch1.Addiere. Dieses Objekt benutzt du aber gar nicht in der Methode. Statt dessen übergibst du dasselbe Objekt nochmals als Parameter. Entweder machst du die Methode static, oder du wirfst einen Parameter raus. So ist das Unsinn. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.