Unterschied zwischen objektorientierter und strukturierter Pogrammierung in C++



  • Kenner der Scene 2 schrieb:

    halloich schrieb:

    Ähm, objektorientierte Programmierung schließt doch strukturierte Programmierung ein. http://de.wikipedia.org/wiki/Strukturierte_Programmiersprache

    Neinein, in C++ sollte man besser nicht strukturiert programmieren.

    Also, so wie ich das verstanden habe, geht es bei der Strukturierten Programmierung darum, dass der Programmablauf strukturiert ist. Also keine goto, sondern Schleifen und Funktionen mit klaren Ein- und Ausgängen. So ist aber jede Methode einer Klasse doch auch aufgebaut.



  • Letztendlich kommt es sowieso darauf an, wie man herangegangen ist, sprich wie man das ganze "designt" hat.
    Man kann z.B. durchaus auch ohne OOP einige Design Patterns (welche ja wohl schon für gutes OOP stehen) implementieren, d.h. OOP an sich heißt noch lange nicht, dass man etwas gut programmiert hat. Es macht einem das Leben allerdings schon einfacher.



  • halloich schrieb:

    Kenner der Scene 2 schrieb:

    halloich schrieb:

    Ähm, objektorientierte Programmierung schließt doch strukturierte Programmierung ein. http://de.wikipedia.org/wiki/Strukturierte_Programmiersprache

    Neinein, in C++ sollte man besser nicht strukturiert programmieren.

    Also, so wie ich das verstanden habe, geht es bei der Strukturierten Programmierung darum, dass der Programmablauf strukturiert ist. Also keine goto, sondern Schleifen und Funktionen mit klaren Ein- und Ausgängen. So ist aber jede Methode einer Klasse doch auch aufgebaut.

    Strukturierte Programmierung: Jede Funktion nur ein return, gar kein break, und am besten nur while.

    Objektorientiertes C++: So viel return wie möglich, break is aber auch OK.

    Grund: In C++ gibts DDESTRUKTOOREN! In Pascal nicht. 🕶



  • Strukturierte Begründung schrieb:

    Objektorientiertes C++: So viel return wie möglich,...

    Schwachfug. Sowas führt früher oder später nur zu beschissenem Code. EIN return pro Funktion sollte die Regel sein, mehrere nur eine Ausnahme. VIELE returns in einer Funktion = schlechtes Design. (Ausnahme es ist ein switch wo pro case ein return steht)

    Daher, wenn überhaupt: So viel return wie NÖTIG... und nicht mehr.

    Abgesehen davon, was hat das mit Destruktoren zu tuen? Die retten Dich auch nicht vor schlechtem Code... Beispiel:

    int func()
       char* x = new char[10000];
    
       if( wasauchimmer==true)
       {
          return;
       }
    
       delete x;
    
       return;
    }
    


  • Strukturierte Begründung schrieb:

    Strukturierte Programmierung: Jede Funktion nur ein return, gar kein break, und am besten nur while.

    Objektorientiertes C++: So viel return wie möglich, break is aber auch OK.

    Ich dem Wikipedia Artikel steht:

    Beispiele für strukturierte Programmiersprachen [Bearbeiten]

    * Algol
    * C

    und in C kann ich auch mehrere return in eine Funktion einbauen.

    Was ich eher als Problem sehe, ist das werfen von Exceptions, weil man damit den strukturierten Ablauf aufbrechen kann und fast wie beim goto plötzlich ganz wo anders sein kann.

    Grund: In C++ gibts DDESTRUKTOOREN! In Pascal nicht. 🕶

    Was soll das für ein Grund sein. In Java gibts auch keine.



  • halloich schrieb:

    Grund: In C++ gibts DDESTRUKTOOREN! In Pascal nicht. 🕶

    Was soll das für ein Grund sein. In Java gibts auch keine.

    Java ist ja auch keine C++-artige Objektorientierung.



  • ganztoll schrieb:

    halloich schrieb:

    Grund: In C++ gibts DDESTRUKTOOREN! In Pascal nicht. 🕶

    Was soll das für ein Grund sein. In Java gibts auch keine.

    Java ist ja auch keine C++-artige Objektorientierung.

    Och ne, jetzt unterscheidet sich objektorientiertes und strukturiertes Programmieren auch noch von Sprache zu Sprache. 🙄



  • Strukturierte Begründung schrieb:

    Grund: In C++ gibts DDESTRUKTOOREN! In Pascal nicht. 🕶

    Das ist nicht OO sondern RAII.



  • halloich schrieb:

    Was ich eher als Problem sehe, ist das werfen von Exceptions, weil man damit den strukturierten Ablauf aufbrechen kann und fast wie beim goto plötzlich ganz wo anders sein kann.

    Unsinn.



  • nep schrieb:

    halloich schrieb:

    Was ich eher als Problem sehe, ist das werfen von Exceptions, weil man damit den strukturierten Ablauf aufbrechen kann und fast wie beim goto plötzlich ganz wo anders sein kann.

    Unsinn.

    Was Wann Wo???



  • halloich schrieb:

    nep schrieb:

    halloich schrieb:

    Was ich eher als Problem sehe, ist das werfen von Exceptions, weil man damit den strukturierten Ablauf aufbrechen kann und fast wie beim goto plötzlich ganz wo anders sein kann.

    Unsinn.

    Was Wann Wo???

    Du meintest, Exceptions seien unstrukturiert. Das Konzept heißt aber nicht ohne Grund „strukturierte Ausnahmebehandlung“.



  • Konrad Rudolph schrieb:

    halloich schrieb:

    nep schrieb:

    halloich schrieb:

    Was ich eher als Problem sehe, ist das werfen von Exceptions, weil man damit den strukturierten Ablauf aufbrechen kann und fast wie beim goto plötzlich ganz wo anders sein kann.

    Unsinn.

    Was Wann Wo???

    Du meintest, Exceptions seien unstrukturiert. Das Konzept heißt aber nicht ohne Grund „strukturierte Ausnahmebehandlung“.

    Naja, man kann ja nicht wieder nach oben springen und wenn mas es so sieht, dass sie von Methode zu Methode weiter geworfen werden, dann kann man schon sagen, dass sie strukturiert sind. Aber ein bisschen was von einem "goto next error label" haben sie schon.



  • halloich schrieb:

    Naja, man kann ja nicht wieder nach oben springen und wenn mas es so sieht, dass sie von Methode zu Methode weiter geworfen werden, dann kann man schon sagen, dass sie strukturiert sind. Aber ein bisschen was von einem "goto next error label" haben sie schon.

    Nicht mehr oder weniger, als ein 'if' oder ein 'for' etwas von 'goto label' haben.



  • Konrad Rudolph schrieb:

    halloich schrieb:

    Naja, man kann ja nicht wieder nach oben springen und wenn mas es so sieht, dass sie von Methode zu Methode weiter geworfen werden, dann kann man schon sagen, dass sie strukturiert sind. Aber ein bisschen was von einem "goto next error label" haben sie schon.

    Nicht mehr oder weniger, als ein 'if' oder ein 'for' etwas von 'goto label' haben.

    Ein if und for kann ich noch in nem Struktogramm darstellen. Wie stellt man Exceptions strukturiert dar?



  • halloich schrieb:

    Konrad Rudolph schrieb:

    halloich schrieb:

    Naja, man kann ja nicht wieder nach oben springen und wenn mas es so sieht, dass sie von Methode zu Methode weiter geworfen werden, dann kann man schon sagen, dass sie strukturiert sind. Aber ein bisschen was von einem "goto next error label" haben sie schon.

    Nicht mehr oder weniger, als ein 'if' oder ein 'for' etwas von 'goto label' haben.

    Ein if und for kann ich noch in nem Struktogramm darstellen. Wie stellt man Exceptions strukturiert dar?

    Gar nicht. Ist aber irrelevant: Wie stellt man Klassen und virtuelle Methodenaufrufe in einem Struktogramm dar? Ebenfalls nicht. Das Struktogramm ist in dieser Hinsicht einfach nicht vollständig. Trotzdem würde niemand auf die Idee kommen zu sagen, virtuelle Methodenaufrufe seien unstrukturiert.



  • Es geht ja nicht darum, dass es sowas im Struktogramm nicht gibt. Bei nem virtuellen Methoden Aufruf bin ich wieder genau da wo ich die Methode aufgerufen habe, wenn sie beendet wurde. Wenn aber ne Exception geworfen wurde, dann bin ich irgendwo wo die Exception gefangen wird und das kann einige Methoden weiter oben sein. Wenn man es so sieht, dass jede Methode die Exception "verarbeitet" und weiter wirft, dann kann man schon sagen, dass es einigermaßen strukturiert abläuft.



  • loks schrieb:

    Strukturierte Begründung schrieb:

    Objektorientiertes C++: So viel return wie möglich,...

    Schwachfug. Sowas führt früher oder später nur zu beschissenem Code. EIN return pro Funktion sollte die Regel sein, mehrere nur eine Ausnahme. VIELE returns in einer Funktion = schlechtes Design. (Ausnahme es ist ein switch wo pro case ein return steht)

    In C++ kannst du doch eh nicht wirkliche den Programm Verlauf bestimmen, da Exceptions von jedem externen Programm-Code aufgerufen werden können oder schreibst du (hoffentlich nicht!!) deine Funktionen immer mit einem try/catch drum rum gewrapt?

    Abgesehen davon, was hat das mit Destruktoren zu tuen? Die retten Dich auch nicht vor schlechtem Code... Beispiel:

    Destruktoren ermöglichen dir hier automatische Ressourcenverwaltung. Aber klar, wenn jemand schlechten Code schreibt dann ist der Code schlecht.



  • Man soll ein großes Projekt auf zwei verschiedene Arten angehen können.

    Möglichkeit 1 (modulare Programmierung)
    Entweder mit der Top_Down Methode, bei der von der konkreten Anwendung, die einem vorschwebt, ausgegangen wird. Man notiert sich zuerst möglichst präzise in Natursprache, was das Programm tun soll. Und dann versucht man, diese Natursprache in die Programmiersprache zu übersetzen. Möglichst Zeile für Zeile. Wenn man feststellt, dass die Programmiersprache für ein Objekt der Natursprache keinen Datentyp zur Verfügung stellt, so erfindet man eine Klasse, deren Datenelemente und Funktionen mit 'einfacheren' Datentypen arbeiten können.
    Wenn auch diese einfacheren Datentypen noch zu komplex sind, modularisiert man weiter. Solange, bis am Ende, 'auf der untersten Ebene', nur noch Klassen übrigbleiben, die in der Tat nur noch int, char usw. als Datenelemente enthalten. Der Ausgangspunkt der Planung ist also das 'fertige' Programm, und es wird immer weiter in kleinere Teileinheiten zerhackt, bis am Ende viele kleine, überschaubare, und einfach implementierbare, MODULE übrigbleiben.
    -> Eine solche Herangehensweise nennt man MODULARE PROGRAMMIERUNG. Wenn dabei auch im Zuge der Vereinfachung des komplexen Endprogrammes Klassen entstehen sollten, so folgt man damit doch nicht einem objektorientierten Programmierparadigma.

    Möglichkeit_2 (objektorientierte Programmierung)
    Alternativ sagt man auch Bottom_Up Methode dazu. Es wird dabei überhaupt nicht von einer konkreten Aufgabenstellung ausgegangen, sonder im Gegenteil - aus den zur Verfügung stehenden 'elementaren' Datentypen (int, char etc.) bastelt man 'auf gut Glück' komplexere Klassen, die ihrerseits diese Datenelemente von 'elementarem' Datentyp enthalten. Weil man noch nicht genau vorhersehen kann, wie eine Funktion konkret mit diesen Daten arbeiten wird, deklariert man die meisten Funktionen, von denen man vorausblickend annimmt, dass sich ihre konkrete Implementierung in einer der abgeleiteten Klassen je nach Aufgabenstellung unterscheiden können wird, als VIRTUAL. Polymorphismus ist das primäre Merkmal einer objektorientierten Herangehensweise an eine Aufgabenstellung. Man behält sich also die konkrete Realisierung von Objekten einer Klasse noch vor. Wenn die Basisklassen klug gewählt werden, gelingt es dann auch auf diese Weise, allmählich das komplexe Programm aus diesen einfacheren Bausteinen zu basteln. Dabei ist es auch von Vorteil, dass man oft bei ähnlichen Aufgabenstellungen bereits einen wiederverwendbaren Grundstock von Klassen zur Verfügung hat, sodass sich auch solche Anwendungen dann viel einfacher und schneller umsetzen lassen -> Und das ist die Zielsetzung bei der OBJEKTORIENTIERTEN Programmierung. Wenn auch die 'fertige' Anwendung am Ende so aussieht, als sei sie klug in viele kleine Teilmodule zerlegt, so ist sie dennoch nicht durch das Befolgen eines modularen Programmierparadigmas entstanden.

    Während man mit der Methode 1) schwerlich damit rechnen können wird, dass die Module in einer anderen Anwendung ohne weiteres wiederverwendbar sein werden, so ist das bei Methode 2) die prinzipielle Absicht.
    Andererseits führt Methode 1) zu einer 'maßgeschneiderten', für diese eine Anwendung idR 'optimierten' Architektur der Anwendung, weil wirklich nur diejenige Funktionalität konkret implementiert wird, die benötigt wird.
    Mit der Methode 2) kann es sehr leicht passieren, dass die Bausteine nicht 100% ig optimal zur Konstruktion einer konkreten Anwendung geeignet sind. (Was man aber in den meisten Fällen trotzdem in Kauf nimmt).

    Nur weil irgendwo mit class Klassen definiert wurden, betreibt man deshalb also noch lange nicht unbedingt objektorientierte Programmierung.
    Umgekehrt ist es ein Irrtum, von Programmiersprachen, die das Wort 'class' überhaupt nicht kennen, anzunehmen, es wäre in solchen Programmiersprachen nicht möglich, 'objektorientiert' zu programmieren (die WinAPI ist ein gutes Beispiel, es gibt Fensterklassen, virtuelle Funktionen werden durch Callback- Funktionen würdig vertreten usw. - d.h. objektorientiert, und das alles, obwohl 'C' nicht einmal das Wort 'class' kennt).

    Objektorientierte und modulare Programmierung können in einer 'fertigen' Anwendung - oberflächlich betrachtet - gar nicht voneinander unterschieden werden. Der Unterschied liegt nur in der Art und Weise, WIE die Anwendung geplant wurde. (Eine strukturierte Programmiersprache verfügt über Anweisungen zur bedingten Ausführung von Codezeilen sowie über Wiederholungsschleifen. Mehr ist dazu nicht nötig. Es gibt wohl einige dutzend 'weithin bekannte' imperative Programmiersprachen, die dem genügen. Wer Lust hat, den gesamten Programmcode in ein einziges Modul zu packen -> Strukturierte Programmierung)



  • Hallo

    Ich finde nicht, daß die Ergebnisse von OO- und modularer Programmierung oberflächlich ununterscheidbar sind.

    Überhaupt:

    Bei der OOP beginnt man damit, sich zu überlegen, welche *Substantive* und welche *Adjektive* in der Problembeschreibung vorkommen.
    Die Substantive modelliert man als Objekte ("wer ?"), die Adjektive als Methoden ("macht was ?").

    Das Ergebnis ist ein *datenorientiertes* Programm, d.h. die Daten (private Daten in den Objekten) bestimmen darüber, was mit ihnen gemacht werden darf
    (welche public-Methoden es gibt).

    Im Gegensatz zu *funktionsorientierten* Programmen, bei denen die Funktionen bestimmen, was sie mit den Daten (die ihnen als Argumenten übergeben werden) machen. So etwas entsteht typischerweise durch Software-Design mit strukturierten Programmiersprachen.

    Auch rein formal ist der Unterschied zwischen einem echten OO-Programm, etwa in Smalltalk, und einem block-strukturiertem Programm, etwa in C, riesig:
    Vergleiche mal einen ST-80-FileOut mit einem C-Quelltext.

    Gruß



  • Vielleicht sollte erst mal jemand überhaupt definieren was mit "objektorientierter Programmierung" gemeint ist 😃


Anmelden zum Antworten