Ich habe ein Problem OPP zu verstehen. Mit solchen Standardbeispielen wie sie in vielen Büchern vorkommen, wie zb. ein Auto(das Auto als Klasse) , komm ich noch klar und versteh es. Aber ich habe keine Ahnung wie man es nutzt, z.B in einen einfachen Programm zur bestimmung der Nullstellen ein quadratischen Gleichung der Form ax^2+bx+x=0 (ich habe das als Beispiel gewählt da ich das schon öfter in verschieden Programmiersprachen geschrieben habe allerdings Prozdural) Wie würde man in dem Beispiell OPP nutzen? MFG
> Wie würde man in dem Beispiell OPP nutzen?
Praktisch gar nicht. Wenn es nur darum geht die Nullstellen einer
quadratischen Gleichung zu finden, bringt dir OOP genau: 0, njente,
nothing.
OOP spielt seine Trümpfe erst bei größeren Projekten aus, wenn
mehrere Teilsysteme zusammenarbeiten müssen.
Aber seis drum.
Du kannst zb. so vorgehen: Nimm dir die Aufgabenstellung her und
lies sie. Alle Hauptwörter die problemrelevant sind, sind erst
mal heisse Kandidaten für Objekte. Diese Objekte mussen Aktionen
ausführen können. Wieder: Schau die Aufgabenstellung erneut durch.
Diesmal aber schon mit dem Wissen welche Objekte es geben wird.
Suche nach Hinweisen, welche Aktionen diese Objekte ausführen müssen.
Die werden dann zu Methoden deiner Objekte.
Wenn du die Aufgabenstellung schon erneut studierst, dann Suche auch
nach Hinweisen, welche Eigenschaften diese Objekte haben können.
Das sind dann heisse Kandidaten für Member-Variablen.
Und vor allen Dingen: Glaube nicht dass dein erster Objektentwurf
der endgültig seligmachende sein wird. Eine Objekthierarchie zu
entwerfen ist sehr oft ein iterativer Prozess. Oft ist es auch
so, dass man während des Design- oder (Gott bewahre) Implementierungs-
prozesses drauf kommt, das man doch daneben liegt und ein
massives Redesign macht. Dank OOP geht das meist auch problemlos.
Wenn die Einzelteile plötzlich wie Puzzlestückchen zueinanderpassen,
dann ist das ein gutes Zeichen.
>das Auto als Klasse
Methoden des Autos: Fahren
Objekte: Motor, Fahrersitz, Rad
Membervariablen: Treibstoff, Farbe, Anzahl der Sitze,
Kofferraumvolumen, Anzahl der Achsen, Anzahl der Räder...
Nach meinem bisherigen Wissen müsste das so sein.
Die Klasse beschreibt IMHO ein Grundgerüst. Dieses kann man dann noch
erweitern (vererben?).
Um da auch mal weiterzuspinnen: Wann macht man etwas als Membervariable und wann leitet man ab? Hilfreich ist es hier sich klar zu machen, welche Beziehung gilt: * Ist-Ein * Hat-Ein Also: zb. Ein PKW ist ein KFZ. D.h. Ich werde eine Klasse PKW von einer Basisklasse KFZ ableiten. Ein LKW ist ebenfalls ein KFZ. Auch eine LKS Klasse wird von KFZ abgeleitet. Aber: Ein PKW hat einen Motor. Es wäre also grundfalsch, wenn man eine PKW Klasse von einer Klasse Motor ableiten würde. Ein PKW ist nun mal kein Motor. Ein Dieselmotor wäre ein Motor, also könnte man eine Klasse Dieselmotor von Motor ableiten. Die Beziehung PKW <-> Motor ist aber hat-ein, daher wird eine PKW Klasse eine Member Variable vom Typ Motor haben. In der Tat ist sogar so, dass das Kennzeichen eines KFZ ja darin besteht, dass es einen Motor hat. D.h. die Motor Membervariable wird man in die KFZ Klasse verschieben. Dadurch erbt die PKW Klasse diesen Motor: auch ein PKW hat damit einen Motor. Genauso wie ein LKW class KFZ { ... Motor m_Motor; }; class PKW : public KFZ { }; class LKW : public KFZ { }; Will man jetzt noch ausdrücken können, dass es verschiedene Motortypen geben kann, dann muss man m_Motor natürlich als Pointer ausführen, denn man benötigt ja Polymorphie und die geht in C++ nur über Referenzen oder Pointer. class Motor { public: int m_PS; }; class DieselMotor : public Motor { }; class BenzinMotor : public Motor { }; class KFZ { public: Motor* m_Motor; }; class PKW : public KFZ { }; class LKW : public KFZ { }; So jetzt kann ich mein Auto beschreiben: Mein Auto ist ein PKW und hat einen Dieselmotor mit 99PS. PKW MeinAuto; MeinAuto.m_Motor = new Dieselmotor; MeinAuto.m_Motor->m_PS = 99; Ich könnte jetzt auf die Idee kommen und aus meinem Auto den Dieselmotor auszubauen und durch einen Benziner mit 120PS zu ersetzen: delete MeinAuto.Motor; MeinAuto.m_Motor = new BenzinMotor; MeinAuto.m_Motor->m_PS = 120; (Disclaimer: Natürlich würde man die Membervariablen in der Praxis nicht public machen. Wurde hier aus Gründen der Tipparbeit so gemacht)
Hier sieht man auch, dass diese Betrachtungsweise nicht immer eindeutig ist. Wenn ich jetzt einen Turbo ins Spiel bringe, wie ist dann der Zusammenhang? Ist mein Motor jetzt ein Turbo-Motor oder hat mein Motor einen Turbo. Je nachdem welche Aufgabenstellung ich lösen möchte, kann einmal die eine und einmal die andere Betrachtungsweise die zielführende sein. Hier sieht man auch wie schlampig wir im täglichen Leben sind. Normalerweise sagen wir: Mein Auto hat einen Turo. Dabei ist es gar nicht das Auto, das über den Turbo verfügt, sondern es ist der Motor meines Autos der den Turbo ins Spiel bringt. Daraus folgt: Die Frage ist nicht wie verhält sich der Turbo in Bezug auf ein KFZ sondern wie ist die Beziehung Turbo zu Motor.
Wann nimmt man OOP, wann programmiert man prozedural? OOP nimmt man, wenn die Daten im Mittelpunkt stehen (z.B. Adressverwaltung), prozedural dann, wenn der Algorithmus im Vordergrund steht (z.B. Sortieralgorithmen, oder embedded-Maschinensteuerung). Natürlich sind OOP und prozedurale Sprachen gleich mächtig, also kann man jedes Problem mit beiden Ansätzen lösen, aber die obige Faustregel hilft!
Wenn du nur Nullstellen von quadratischen Funktionen suchst, sehe ich auch keinen sinnvollen Einsatz von OOP. Wenn es dagegen z.B. um einen Algorithmus geht, der die Nullstellen einer Funktion benötigt, könnte es so aufgebaut werden: Klasse Funktion Methoden: Funktionswert(x), Ableitung(x), Nullstelle(x) Klasse Polynom wird von Klasse Funktion abgeleitet. Membervariablen: Koeffizienten[1..n] Die Methode Nullstelle(x) soll eine Nullstelle in der Nähe von x berechnen. Die Klasse Funktion würde hierfür das Newtonverfahren anwenden. Die Klasse Polynom überlädt die Funktion Nullstelle: wenn der Grad des Polynoms <=4 ist, werden die Nullstellen analytisch berechnet. Sonst wird Nullstelle(x) der Superklasse aufgerufen. Nun kann ein Progrämmchen, das z.B. die Funktion plottet und jeweils ein Kreuz bei den Nullstellen macht, ohne Kenntnis des Verfahrens zur Nullstellensuche geschrieben werden, da dieses Verfahren als Methode zum Objekt der Klasse Funktion gehört und nicht mehr im Progrämmchen implementiert werden muss. OOP kann im Bereich der Numerik das Programmieren stark vereinfachen (und dabei die Laufzeit gar nicht mal so sehr verlängern). Jens
> Klasse Polynom wird von Klasse Funktion abgeleitet. > Membervariablen: Koeffizienten[1..n] Das könnte man jetzt noch weiter treiben: Anstatt nur die Koeffizienten abzuspeichern, könnte man einen eigenen Polynomterm einführen, der aus Koeffizient Exponent besteht. Wer sagt dann eigentlich, dass es in einem Polynomterm immer nur um x, geht. Dort könnte auch ein normaler arithmetischer Ausdruck stehen. Also: neue Member für Polynomterm Koeffizient Ausdruck Exponent Damit könnte man dann auch 'Polynome' der Gestalt 3*(x-5)^2 + ( 2*x + 9) + 15 auf Nullstellen untersuchen. Das erste was der Nullstellenlöser dann machen muesste, ist zunächst mal die Klammern loszuwerden und das Polynom zu vereinfachen. Da gehts dann allerdings schon in den Bereich 'Symbolic Computation' hinein. Ist letztendlich alles nur eine Frage was man damit erreichen möchte. Wenn es nur darum geht das klassische x^2 + px + q = 0 zu lösen, dann ist das alles mit Kanonen auf Spatzen geschossen. Eine Funktion die p p x = - --- + sqrt( ( --- ) ^2 - q ) 1,2 2 - 2 berechnet ist ein 10 Zeiler. Obwohl: so simpel ist das auch wieder nicht, wenn man jetzt noch in die Berücksichtigung numerischer Stabilität hineingeht.
Die Wurzel zu berechnen dauert aber etwas. Auf einem embedded System ohne OS muss man mit sowas vorsichtig sein, sonst frisst ein Prozess die Rechenzeit und blockiert andere.
Erleuchte mich. Wie löst du eine quadratische Gleichung ohne die Verwendung einer Wurzel. Newton Iteration?
Stimmt. Hierfür bietet sich das Heron-Verfahren an. Dies ist ein Spezialfall des Newton-Verfahrens und auch als Babylonisches Wurzelziehen bekannt. Gruß
Ach, jetzt versteh ich! Ihr schlagt vor nur für die Wurzel in obiger Gleichung etwas anderes zu verwenden. Ich dachte ihr hättet eine Lösungsformel für x^2 + px + q = 0 die ohne Wurzel auskommt.
Ich habe da auch noch ne C++ Frage.Was sind Konstruktoren und Destruktoren? Und wofür brauch man sie überhaupt? Ist es zwingen erforderlich das man sie definiert? Gruss Frank
Genz ehrlich: Es wäre besser, wenn du dir ein Lehrbuch über C++ besorgst. Das Thema Konstruktor/Destruktor ist ein überaus zentrales Thema in C++, wenn du darüber nichts weist, heist das, dass dir massig Grundlagen abgehen. In aller Kürze: Ein Konstruktor ist eine Funktion die immer aufgerufen wird. wenn ein Objekt 'ins Leben gerufen wird'. Die Umkehrung davon ist der Destruktor, der immer aufgerufen wird, wenn ein Objekt stirbt. Zwingen erforderlich ist keines von beiden. Es hängt immer davon ab, was sich innerhalb des Objekts befindet, welche Member-Variablen es besitzt. Initialisieren sich die Member selbst (haben die also selbst einen Konstruktor) braucht man normalerweise selbst keinen Konstruktor. Tun sie das nicht (wie zb. bei einem int, long, double oder einem Pointer) ist es ratsam einen Konstruktor zu definieren, damit diese Member Variablen garantiert auf einen gültigen Wert initialisiert werden. Einen Destruktor braucht man eigentlich nur dann, wenn die Klasse in irgendeiner Form Resource-Management macht. Dann ist der Destruktor die geeignete Stelle um diese Resourcen wieder frei zu geben. Und natürlich: Wenn man von dieser Klasse wieder eine andere Klasse ableitet, die man polymorph löschen können möchte. Dann ist ein virtueller Destruktor eine notwendige Voraussetzung. Aber wie bereits angeklungen: Das ist ein Thema, dass sich in so einem Forum nur schlecht abhandeln lässt. Jedes schlechtere Lehrbuch hat ein eigenes Kapitel über diese Thematik.
Noch was. Es gibt da eine Faustregel, die besagt: Wenn man eines der 3: * Destruktor * Copy Konstruktor * Zuweisungsoperator braucht, dann braucht man meistens alle 3
Hallo Danke für die Antwort. Ich habe gerade erst angefangenmit C++. Ich habe mir ein paar Bücher geholt, aber ich finde irgendwie keins was für Anfänger so richtig geeignet ist.Die Beispiele sind immer irgendwelche Malprogramme o.ä.! Überhaupt nicht praxis bezogen. Kannst Du mir noch ein gutes Anfänger Buch empfehlen. Ich möchte dann mit Visual C++ arbeiten, wenn ich die Materie einigermassen verstanden habe. Frank
> Die Beispiele sind immer irgendwelche Malprogramme o.ä.! Überhaupt > nicht praxis bezogen Was ist an einem Malprogramm nicht praxisbezogen? In so einem Program kann man wunderbar die wichtigsten Grundelemente unterbringen: Da gibt es eine ganze Reihe von unterschiedlichen Klassen die verschiedene Elemente des Malprogrammes modellieren. Da gibt es geometrische Formen die von einer gemeinsamen Basis- klasse ableiten. Diese Formen haben bis zu einem gewissen Grad die gleichen Verhaltensweisen und Aktionskonzepte, die sie aber unterschiedlich implementieren müssen. Da kommt schon mal Polymorphie ins Spiel. Und alles was damit zusammenhängt. Da gibt es Klassen die Malwerkzeuge repräsentieren Da gibt es Klassen die Malflächen repräsentieren Vielleicht geht der Autor auch noch weiter und führt Malaktionen ein. Damit baut er sich den Weg zu Undo/Redo Funktionalität auf und zeigt wie man mit einer Kommando-Basisklasse und wieder Polymorpie, gekoppelt mit einer Verwaltungsklasse sowas realisieren kann. ... Summa summarum ist das ein relativ gutes Beispiel (da überschaubar) wie man OOP Konzepte in einem Program umsetzen kann. Ansonsten würde ich dir einen Blick in den Klassiker empfehlen: Stroustrup, The C++ Programming Language Keine Ahnung ob es davon eine deutsche Übersetzung gibt, ich les sowas grundsätzlich im Original.
>> Die Beispiele sind immer irgendwelche Malprogramme o.ä.! Überhaupt >> nicht praxis bezogen > >Was ist an einem Malprogramm nicht praxisbezogen? >In so einem Program kann man wunderbar die wichtigsten Grundelemente >unterbringen: Wird aber meistens nicht gemacht, weil die Malprogramme in Büchern vorkommen, bei denen mehr auf MFC oder was auch immer eingegangen wird als auf C++. Tip: Bücher in denen im Titel der name "Visual Studio" vorkommt, eignen sich meistens nicht um eine Sprache zu lernen.
> Tip: Bücher in denen im Titel der name "Visual Studio" vorkommt, > eignen sich meistens nicht um eine Sprache zu lernen. Da hast du allerdings recht :-) Nur muss man aber zur Ehrenrettung der Autoren auch sagen, dass ansonsten der zulässige Umfang bei Weitem gesprengt werden würde. Eine Einführung in Programmierung ist kein kleines Unterfangen. Dazu eine Einführung in die Programmiersprache der Wahl, ebenfalls kein kleines Unterfangen. Dazu dann noch eine Einführung in Konzepte und Programmierung von Windows - ebenfalls kein Honiglecken Und dann noch zum drüberstreuen: MFC
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.