Forum: PC-Programmierung Wer kann mir OPP näherbringen


von ich (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

> 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.

von ich (Gast)


Lesenswert?

ups, ich überall opp geschrieben ich mein natürlich oop

von inoffizieller WM-Rahul (Gast)


Lesenswert?

>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?).

von Karl heinz B. (kbucheg)


Lesenswert?

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)

von Karl heinz B. (kbucheg)


Lesenswert?

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.

von Klaus______ (Gast)


Lesenswert?

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!

von Jens (Gast)


Lesenswert?

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

von Karl heinz B. (kbucheg)


Lesenswert?

> 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.

von Jürgen Schuhmacher (Gast)


Lesenswert?

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.

von Karl heinz B. (kbucheg)


Lesenswert?

Erleuchte mich.
Wie löst du eine quadratische Gleichung ohne die Verwendung
einer Wurzel.
Newton Iteration?

von gast (Gast)


Lesenswert?

Stimmt. Hierfür bietet sich das Heron-Verfahren an. Dies ist ein
Spezialfall des Newton-Verfahrens und auch als Babylonisches
Wurzelziehen bekannt.

Gruß

von Karl heinz B. (kbucheg)


Lesenswert?

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.

von Fran (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl heinz B. (kbucheg)


Lesenswert?

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

von Frank (Gast)


Lesenswert?

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

von Karl heinz B. (kbucheg)


Lesenswert?

> 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.

von Bartli (Gast)


Lesenswert?

>> 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.

von Karl heinz B. (kbucheg)


Lesenswert?

> 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
Noch kein Account? Hier anmelden.