Forum: PC-Programmierung Wieso Objektorientiert?


von Ovo (Gast)


Lesenswert?

Hallo,

der Titel sagt's eigentlich schon: Wieso Objektorientiert?


Ich versuche momentan mir noch einmal einen Ruck zu geben mit OO 
Programmierung anzufangen, bisher drücke ich mich (erfolgreich) um 
dieses Thema und komme super zurecht.

Ich kann einfach keinen Vorteil für mich bzw. meine Programme sehen die 
mir OO bringen würde. Warum sollte ich OO verwenden? Was bietet mir ein 
Objekt, was nicht auch eine gute Funktion bietet?
Ich habe nun schon ein paar Bekannten diese Frage gestellt, 
zufriedenstellend beantworten konnte sie aber niemand. Deshalb hoffe ich 
auf euch!

Nur um irgendein Beispiel zu nennen:

Ich benutze seit Jahren meine UART Funktion und gebe sie auch gerne 
anderen die diese einfach benutzen können. Wieso sollte man diese 
Funktion nun OO umsetzen?
Den Code der Funktion selbst muss man, genau wie bei einem Objekt, weder 
kennen noch verstehen. Die Funktion bekommt einfach gesagt was sie 
machen soll, erneut wie bei einem Objekt. Was sie nun genau und vor 
allem wie sie macht kann dem Anwender völlig schnuppe sein.

Funktion:
senden(Schnittstelle1, "Hallo Welt");

Objekt:
x = new senden();
x.schnittstelle(Schnittstelle1);
x.senden("Hallo Welt");


Genauso wie ich bei der Funktion kurz in den Kopf schauen muss um zu 
sehen was ich übergeben kann/muss und was die Funktion genau kann, muss 
ich in die Dokumentation der Klasse schauen um herauszufinden was diese 
kann/benötigt.



Somit kommen wir wieder zur Eingangsfrage: Ich habe schon verstanden was 
es mit Klassen, Vererbungen, etc. etc. auf sich hat, aber wo ist genau 
der Vorteil zu Prozeduralen Programmen die aus Funktionen und Statischen 
Elementen aufgebaut sind?

von Borislav B. (boris_b)


Lesenswert?

Ein Objekt kapselt nicht nur Funktionalität, sondern auch einen Zustand. 
Das ist etwas was du ohne Objektorientierung nur schwer nachbilden 
kannst. Ohne dieses wirst du schwerlich eine brauchbare Architektur auf 
die Beine stellen können.

von Mark B. (markbrandis)


Lesenswert?

-Zusammenfassung von Datenstrukturen und den Funktionen, die auf ihnen 
operieren
-Durch Vererbung Abbilden einer Hierarchie in der Software, wie sie der 
realen Welt entspricht (z.B. Lassie ist ein Collie ist ein Hund ist ein 
Säugetier ist ein Lebewesen...)
-Kapselung von Daten (man kann nicht direkt auf alles zugreifen, sondern 
nur über vordefinierte Methoden)

von Borislav B. (boris_b)


Lesenswert?

Ovo schrieb:
> Was bietet mir ein
> Objekt, was nicht auch eine gute Funktion bietet?

Und ich glaube du hast da noch ein kleines Verständnisproblem. Ein 
Objekt soll ja keine Funktionen ersetzen. Ganz im Gegenteil, ein Objekt 
bietet selber Funktionen an (Methoden).

Wenn du ein Haus baust, willst du ja auch eine Küche, ein badezimmer, 
einen Keller usw. haben. Oder würdest du einfachen einen 50m*50m*50m 
Kubus hinklatschen, und da einfach alle Möbel reinschütten? ;-)

von Mario S. (Gast)


Lesenswert?

Du brauchst OOP normalerweise nicht bei Mikrocontroller-Steuerung, 
Kommunikationsstack ...

Bei PC Programmen wo eher Daten verarbeitet werden oder grafischen Tools 
schon.

von Toni (Gast)


Lesenswert?

OOP wurde damals gemeinsam mit "Xtreme Programming (XP)" eingeführt. Von 
beidem ist nicht viel zu halten.

Solange du keinen Säugetier-Zoo programmierst, ist prozedural genauso 
gut.

von Mark B. (markbrandis)


Lesenswert?

Eine grafische Benutzeroberfläche ohne OOP zu schreiben will sich wohl 
niemand freiwillig antun ;-)

von Mark B. (markbrandis)


Lesenswert?

Toni schrieb:
> OOP wurde damals gemeinsam mit "Xtreme Programming (XP)" eingeführt. Von
> beidem ist nicht viel zu halten.

Völlig falsch, OOP ist viel älter als der Begriff "Extreme 
Programming". Letztzeres wurde in der 90er Jahren definiert. OOP mit 
Smalltalk gab es schon in den 70er Jahren.

von Toni (Gast)


Lesenswert?

Mark Brandis schrieb:
> Völlig falsch, OOP ist viel älter als der Begriff "Extreme
> Programming".

Ja ok hast recht.

Mark Brandis schrieb:
> Eine grafische Benutzeroberfläche ohne OOP zu schreiben will sich wohl
> niemand freiwillig antun ;-)

Eine GUI wird normalerweise nicht mehr "geschrieben".
Und ob ohne oder mit OOP macht keinen grundsätzlichen Unterschied.

von Informatiker (Gast)


Lesenswert?

Für "kleinere" Programme (d. h. z. B. im Embedded Bereich) mag ja das 
prozedurale Vorgehen noch funktionieren. Schwierig wird es erst bei 
komplexerer Software (z. B. PC-Anwendungen), in der viele Komponenten 
zusammenspielen und zur Laufzeit hinzugefügt und entfernt werden. Ein 
Softwarebiotop mit vielen verschiedenen Objekten, die zusammenspielen, 
wird ohne objektorientierte Programmiersprache sehr schnell extrem 
unübersichtlich. In prozeduralen Lösungen werden auch oft die 
objektorientierten Konzepte ab einem bestimmten Komplexitätsgrad der 
Software nachgebildet. Z. B. virtuelle Methodentabellen, 
Datenbeziehungen, etc. Das geht natürlich auch, ist aber wesentlich 
aufwändiger, da der OO-Verwaltungscode ja selbst geschrieben werden 
muss. Das nimmt einem in der OO-Sprache der Compiler alles ab. Dadurch 
wird der Code wesentlich schlanker und ist zielgerichteter formulierbar.

Prozedurale Lösungen werden dagegen oft im Embedded-Bereich bevorzugt, 
weil dort strengere Vorgaben für Determinismus herrschen. Ein 
dynamischer Objektverwalter für das Speichermanagement, der im 
Hintergrund läuft, wie bei Microsoft.NET ist dort meist nicht 
wünschenswert. Da ja z. B. sich der Motor am Controller weiterdreht und 
nicht auf den Speichermanager warten kann (wie der Anwender vor dem PC 
;-).

von Michael B. (laberkopp)


Lesenswert?

> Ohne dieses wirst du schwerlich eine brauchbare Architektur auf
> die Beine stellen können

Auch wenn du es nicht glaubst weil du es nicht kannst,
ist das schon vielen Leuten vor dir gelungen.

> Eine grafische Benutzeroberfläche ohne OOP zu schreiben will sich wohl
> niemand freiwillig antun ;-)

Na ja, eher umgekehrt: Ob Xerox Alto (Mesa) GEM (PL/M) oder Windows (C 
ohne ++) oder Amiga (BCPL) oder Mac (Pascal), es waren alles 
nicht-objektorientierte Programmiersprachen für die GUI, und die 
nachfolgende Vergewaltigung (MFC als C++ Implementation von Windows) 
kann eher als bös gescheitere Katastrophe angesehen werden.

von Udo S. (urschmitt)


Lesenswert?

Toni schrieb:
> OOP wurde damals gemeinsam mit "Xtreme Programming (XP)" eingeführt. Von
> beidem ist nicht viel zu halten.

Da spricht wohl der Profi. Auf die Begründung wäre ich gespannt.

von michael (Gast)


Lesenswert?

Toni schrieb:
> Solange du keinen Säugetier-Zoo programmierst, ist prozedural genauso
> gut.

Was meinst du mit Säugetier-Zoo? Diese etwas praxisfremden Beispiele aus 
Einführungen in die Objektorientierung? So nach dem Motto Ein Schimpanse 
ist ein Affe ist ein Säugetier und erbt deshalb alles, was Säugetiere 
und Affen können? Da geht es wirklich nur darum, Grundlagen zu 
vermitteln. Praxisrelevante Beispiele sollen da nicht gezeigt werden.


Gut gemachte OOP hat insbesondere bei der Wiederverwendbarkeit und 
Erweiterbarkeit von Code große Vorteile gegenüber rein prozeduralem 
Code.
Einen guten Eindruck davon erhält man, wenn man sich mit 
objektorientierten Entwurfsmustern beschäftigt und sich auch einige 
konkrete Beispiele (z.B. die Stromklassen aus Java) anschaut.

Toni schrieb:
> Eine GUI wird normalerweise nicht mehr "geschrieben".
> Und ob ohne oder mit OOP macht keinen grundsätzlichen Unterschied.

Aber wenn du eine GUI "malst" wird im Hintergrund von deiner IDE Code 
erstellt. Und dieser Code dürfte heute in den meisten Fällen 
objektorientiert sein.

Viele Grüße
Michael

von Udo S. (urschmitt)


Lesenswert?

Ovo schrieb:
> Funktion:
> senden(Schnittstelle1, "Hallo Welt");
>
> Objekt:
> x = new senden();
> x.schnittstelle(Schnittstelle1);
> x.senden("Hallo Welt");

völlig falsches Verständnis

OO:
Uart uart1 = new Uart(uartParameter1);
Uart uart2 = new Uart(uartParameter2);

uart1.sende(String1);
Byte[] vonU2 = uart2.empfange();
uart1.....
....
uart1.close();
...

Und OO ist noch viel mehr.

von Christopher C. (Gast)


Lesenswert?

Michael Bertrandt schrieb:
> Na ja, eher umgekehrt: Ob Xerox Alto (Mesa) GEM (PL/M) oder Windows (C
> ohne ++) oder Amiga (BCPL) oder Mac (Pascal), es waren alles
> nicht-objektorientierte Programmiersprachen für die GUI, und die
> nachfolgende Vergewaltigung (MFC als C++ Implementation von Windows)
> kann eher als bös gescheitere Katastrophe angesehen werden.

C/Pascal (die anderen kenne ich nicht so genau) hindert dich nicht OOP 
anzuwenden.

von Udo S. (urschmitt)


Lesenswert?

michael schrieb:
> Stromklassen
???
Meinst du input und output Streams, dann noch die reader und writer 
Klassen dazu, das ist das erste saubere und komplette Interface zur 
exakten Trennung von Binärwerten und Character, das ich gefunden habe.

von Fux (Gast)


Lesenswert?

Michael Bertrandt schrieb:
> Amiga (BCPL)

Intuition wurde nicht in BCPL geschrieben, sondern in C. Und Intution 
war durchaus objektiorientiert. Nur weil die Sprache objektorientierte 
Programmierung nicht unterstuetzt, muss man auf objektorientierte 
Konzepte nicht verzichten. Das noch spaeter eingefuehrten BOOPSIE hat 
das noch deutlicher gezeigt.

Diese ganzen Abgrenzungsdiskussionen sind sowieso idiotisch - ein guter 
Entwickler bedient sich des Paradigmas, das zum Problem passt. Die 
Uebergabe zwischen prozeduraler, modularer und objektorientierter 
Entwicklung sind sowieso fliessend.

von michael (Gast)


Lesenswert?

Michael Bertrandt schrieb:
> Na ja, eher umgekehrt: Ob Xerox Alto (Mesa) GEM (PL/M) oder Windows (C
> ohne ++) oder Amiga (BCPL) oder Mac (Pascal), es waren alles
> nicht-objektorientierte Programmiersprachen für die GUI, und die
> nachfolgende Vergewaltigung (MFC als C++ Implementation von Windows)
> kann eher als bös gescheitere Katastrophe angesehen werden.

von MFC mag man halten was man will. Aber mit .net kriegt man eine GUI 
sicherlich leichter hin als direkt auf der Windows C-Api.

von michael (Gast)


Lesenswert?

Udo Schmitt schrieb:
> Meinst du input und output Streams, dann noch die reader und writer
> Klassen dazu,

Genau das meine ich. Du kannst diesen Klassen leicht neue Funktionalität 
hinzufügen, ohne dass du bestehenden Code ändern musst. Du musst einfach 
einen neuen Decorator implementieren und auf bereits bestehende 
Stream-Objekte anwenden. Leichte Wiederverwendung und Erweiterung, ohne 
dass bestehender Code geändert werden muss.

http://de.wikipedia.org/wiki/Decorator

von Toni (Gast)


Lesenswert?

OOP:
Ich habe keine Ahnung von Datenstrukturen, zusätzlicher Overhead stört 
mich nicht bzw. bin ich von Arduino gewöhnt, und optimierten Code 
braucht heutzutage sowieso keiner mehr.

von Fux (Gast)


Lesenswert?

Deine Funktion senden() ist schoen knapp bemessen. Ich brauche eine 
Version mit einem Parameter fuer blocking I/O. Und natuerlich wirst du 
auch noch eine Empfangsfunktion haben. Dann sieht das also so aus:

senden(Schnittstelle1, Blocking, "Hallo Welt");
empfangen(Schnittstelle1, Blocking, Buffer, BufferSize);

Irgendwie ungeschickt, wenn ich Funktionen habe, die irgendwas machen 
und dann senden und empfangen aufrufen, aber nicht wissen, ob sie 
blocken sollen oder nicht, muss ich diese Parameter auch mitgeben:

sendeHallo(Schnittstelle1, Blocking);

Besser, ich sammle die Optionen in einer Struktur:

struct Serial
{
  Schnittstelle schnittstelle;
  BlockingMode blockingMode;
}

Dann sehen senden und empfangen so aus:

Serial serial;

serial.schnittstelle = Schnittstelle1;
serial.blockingMode = Blocking;

senden(&serial, "Hallo Welt");
empfangen(&serial, Buffer, BufferSize);
sendeHallo(&serial);

Oder eben

Objekt:
Serial serial;

serial.schnittstelle = Schnittstelle1;
serial.blockingMode = Blocking;

serial.senden("Hallo Welt");
serial.empfangen(Buffer, BufferSize);
serial.sendeHallo();

Merke: Objekte sind oft naeher, als man denkt. Und auch billiger, als 
man befuerchtet.

von Christopher C. (Gast)


Lesenswert?

Toni schrieb:
> OOP:
> Ich habe keine Ahnung von Datenstrukturen, zusätzlicher Overhead stört
> mich nicht bzw. bin ich von Arduino gewöhnt, und optimierten Code
> braucht heutzutage sowieso keiner mehr.

OOP bringt zwangsläufig keinen zusätzlichen Overhead, vorallem wenn der 
Compiler etwas vom Optimieren versteht. Man sollte sich allerdings 
informieren wie die Sprache OOP technisch umsetzt um unnötigen Overhead 
zu vermeiden.

von michael (Gast)


Lesenswert?

Toni schrieb:
> OOP:
> Ich habe keine Ahnung von Datenstrukturen, zusätzlicher Overhead stört
> mich nicht bzw. bin ich von Arduino gewöhnt, und optimierten Code
> braucht heutzutage sowieso keiner mehr.

Man kann auch in Assembler wunderbar ineffizienten Code schreiben. Viele 
Datenstrukturen lassen sich mit OOP wunderbar umsetzen. Bsp.: STL in 
C++.

Und: Wenn mich ein wenig zusätzlicher Overhead wirklich nicht stört, ich 
dafür aber viel schneller mit einem Programm fertig bin, dann 
programmiere ich halt mit etwas Overhead.

von Udo S. (urschmitt)


Lesenswert?

Toni schrieb:
> OOP:
> Ich habe keine Ahnung von Datenstrukturen, zusätzlicher Overhead stört
> mich nicht bzw. bin ich von Arduino gewöhnt, und optimierten Code
> braucht heutzutage sowieso keiner mehr.

Du hast also keine Ahnung davon, aber du sagst erst mal das ist 
Blödsinn.

Das gleiche mit "extreme Programming" davon weisst du wohl auch nicht 
viel, schon mal 3 Monate ausprobiert?


Prima, mit der Einstellung würden wir heute immer noch in der Höhle am 
Feuer sitzen und hätten noch nicht mal das Rad erfunden.
Ach so, das Feuer auch nicht, du müsstest deine Würmer also roh futtern 
:-)

von cppler (Gast)


Lesenswert?

Es gibt mehrere Vorteile:
1. Vererbung
2. Überschreiben von Memberfunktionen
3. Templates
4. Operatordeklarationen
...

Der Unterschied zwischen OO und Funktionen liegt in der Kapselung des 
gesamten Kontextes.

von W.S. (Gast)


Lesenswert?

Ovo schrieb:
> Ich versuche momentan mir noch einmal einen Ruck zu geben mit OO
> Programmierung anzufangen

nanana..

Du erwartest zum einen zu viel und hast zum anderen zu wenig 
Vorstellung, wie sowas in der Praxis aussieht.

Also: erster Fall:
Objekte sind - um es mal salopp in plain C zu sagen - struct's, wo nicht 
nur Daten, sondern auch Funktionspointer drinstehen. Das sind die sogen. 
Methoden und so ein Konstrukt ist an einigen Stellen durchaus sinnvoll.

Stell dir mal vor, so eine Methode (bzw. in deiner prozeduralen Version 
so eine Funktion) soll einerseits irgendwelche Daten errechnen und 
andererseits ein Signal abgeben, ob dies geklappt hat oder nicht. 
Natürlich kannst du ne Funktion schreiben
bool ErrechneEs (datentyp* MeineDaten);
und mit
 if (ErrechneEs(&aktuelleDaten)) { ....
benutzen, wobei die Funktion über den Parameterzeiger die Daten schreibt 
und als eigentliches Resultat true oder false zurückgibt. Problem dabei 
ist die fehlende Kapselung, die bei etwas komplexeren Anwendungen 
erfordert, daß man höllisch achtgeben muß, welche Funktionen wie und 
wann auf welche Daten zugreifen dürfen oder nicht. Na klar, sowas geht, 
aber es ist irgendwann stressig.

Mit einem Objekt (in C nachgebildet) sieht das ganz anders aus:
if (aktuelleDaten.ErrechneEs()) {...
womit ein Vertun beim Zuordnen von Daten und Funktion von selbst 
vermieden ist.

Nächster Fall, Menüsysteme. Das ist der eigentliche Kernbereich für das 
Verwenden von Objekten - jedenfall wenn man das "Geräte-Gesicht" in Form 
eines bunten Bildschirms (TFT..) gestaltet hat. Dort müssen die 
verschiedenen sichtbaren Elemente zum einen dargestellt werden und zum 
anderen auf externe Einflüsse reagieren.

Natürlich könnte man die gesamte Darstellung in einer riesigen Funktion 
unterbringen und auch das Reagieren auf Äußeres ebenfalls in einer 
riesigen Funktion mit unzähligen if's und switch's, aber versuch mal, 
bei so einer Implementation irgend eine Kleinigkeit ändern zu wollen - 
da kriegst du ne Krise..

Also muß man es so halten, daß ein jegliches Element sich selbst 
zeichnet und selbst auf Äußeres reagiert und dies auch von seinen 
Subviews, also seinen enthaltenen Objekten erwartet. Da kommt dann das 
Stichwort "Ereignisgesteuert" ins Spiel, was du bei deiner bisherigen 
prozeduralen Programmierweise garnicht hattest. Aus äußeren 
Veränderungen, also z.B. Benutzeraktionen oder daß eine bestimmte Zeit 
verstrichen ist oder daß irgendein Teil des Gerätes jetzt ein Ergebnis 
hat oder eine Position von einem Sensor erkannt wurde oder sonstwas 
eben, wird eine Ereignis-Botschaft (ein Byte oder Word mit bestimmtem 
Inhalt eben) generiert, die in eine Ereignis-Warteschlange (Ringpuffer) 
eingereiht wird und ein anderer Teil der Firmware schaut regelmäßig nach 
dieser Warteschlange und schmeißt etwaige Botschaften dem ganzen 
Menüsystem in den Rachen. Diese leitet dann die Botschaft allen in Frage 
kommenden Objekten zu und das, was sich dafür interessiert, mag es 
auswerten und in seiner Weise drauf reagieren. Das ist ne ganz andere 
Herangehensweise, als man es prozedural gewöhnt ist, also so, wie man 
Programmabläufe auf der Wandtafel aufmalt.

Dein Problem sehe ich eigentlich nur darin, daß man in C keine Objekte 
im Sprachumfang hat und sich deshalb selbst sowas konstruieren muß, und 
daß man in C++ zwar Objekte haben kann, aber diese Spracherweiterung 
eher krötig, noch schlechter lesbar als C und nicht wirklich nett 
gemacht ist und man für Pascal, wo Objekte mittlerweile zum üblichen 
Sprachumfang gehören und auch gut gemacht sind, für die Verwendung auf 
µC zumeist keinen Compiler bekommt, diese Sprache also nicht wirklich 
nutzen kann.


W.S.

von Simon S. (-schumi-)


Lesenswert?

Ich tendiere zur Zeit auch immer mehr dazu, OOP ein wenig in C 
nachzubilden, das sieht dann z.B. so aus (AVR):
1
type_ROTARYENC   encoder_A;
2
type_ROTARYENC   encoder_B;
3
4
// Rotary encoder A  configuration
5
  encoder_A.ddr = &DDRC;
6
  encoder_A.port = &PORTC;
7
  encoder_A.pin = &PINC;
8
  encoder_A.pinNr_A = PC6;
9
  encoder_A.pinNr_B = PC5;
10
  encoder_A.internPullup = True;
11
  encoder_A.autoAcceleration = True;
12
  encoder_A.accerelationFactor = 200;
13
14
// Rotary encoder B  configuration
15
  encoder_B.ddr = &DDRC;
16
  encoder_B.port = &PORTC;
17
  encoder_B.pin = &PINC;
18
  encoder_B.pinNr_A = PC3;
19
  encoder_B.pinNr_B = PC2;
20
  encoder_B.internPullup = True;
21
  encoder_B.autoAcceleration = True;
22
  encoder_B.accerelationFactor = 100;
23
24
// INIT rotary encoders
25
  ROTARYENC_INIT(&encoder_A);
26
  ROTARYENC_INIT(&encoder_B);
27
28
// Muss alle paar ms aufgerufen werden (Timer-ISR o.ä.):
29
  ROTARYENC_RUN(&encoder_A);
30
  ROTARYENC_RUN(&encoder_B);
31
32
// Dann, wo auch immer man die Drehgeber auslesen will
33
  VeraenderungSeitLetztemAuslesen = ROTARYENC_GET(&encoder_A);
34
  GesamtDrehZaehler += ROTARYENC_GET(&encoder_B);
Umgesetzt ist das einfach mit einem typedef-struct, das sowohl die 
Einstellungen für dieses Objekt, als auch Zwischenergebnisse der 
Funktionen (die einen Pointer auf die Struktur erhalten) enthält.
Das hab ich so gemacht, weil:
 - Um mehr/weniger Drehgeber zu benutzen, muss ich nur eine zusätzliche 
Struktur vom type "type_ROTARYENC" anlegen, die Parameter setzen und los 
gehts. Sonst kein zusätzlicher Code
 - Wo welcher Drehgeber angeschlossen ist etc., steht nicht in 
irgendeiner ROTARYENC.h o.ä., sondern in meiner main.c

Vor allem der erste Punkt ist ein wirklich großer Vorteil. Deshalb hab 
ich dieses System inzwischen auch übernommen für:
 - LC-Displays mit HD44780 Controller
 - Taster
 - ADC (verschiedene Channels)
 - Menüsteuerung
 - System, mit dem Unterprogramme in regelmäßigen Abständen automatisch 
aufgerufen werden (ein kleiner Hintergrund-Scheduler quasi, dort kann 
man z.B. wunderbar die DREHGEBER_RUN(&device) eintragen)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Kurzfassung:

Den Sinn von Programmierparadigmen versteht man meist erst dann richtig,
wenn man selber ein größeres Stück Software damit geschrieben hat.

Ovo schrieb:
> Ich versuche momentan mir noch einmal einen Ruck zu geben mit OO
> Programmierung anzufangen

Lass das sein: Ein Ruck bedeutet Gewalteinwirkung, und damit lernst du
OOP eher nicht.

Besser: Versuche einfach, deinen gewohnten Nicht-OO-Programmierstil
dahingehend zu verbessern, dass du auch größere Programme möglichst
übersichtlich gestaltest, duplizierten Code vermeidest und jedes Stück
Code so schreibst, dass du es später mit Erweiterungen an möglichst
wenigen Stellen für ähnlich geartete Aufgabenstellungen verwenden
kannst. Dann wirst du mit hoher Wahrscheinlichkeit ganz von selber und
sanft und gewaltfrei in die OOP hineingezogen werden.


Langfassung:

Wenn du andere fragst, warum sie OOP so toll finden, werden sie dir
entweder einen langen Vortrag über die theoretischen Hintergründe von
OOP halten, eine Marketing-Präsentation mit vielen Buzzwords geben, ein
paar einfache Beispiele nennen, die einzelne Aspekte von OOP beleuchten,
oder dir ein Monstersoftwareprojekt, bei dem sie OOP schon erfolgreich
angewandt haben, im Detail erklären.

Dem theoretischen Vortrag wirst du nicht folgen können, zumal es
wahrscheinlich gar nicht möglich ist, dei Vorteile von OOP rein
theoretisch abzuhandeln. Die Marketing-Präsentation wird sich vielleicht
gut anhören, am Ende wirst du aber nur wissen dass OOP ganz toll ist,
aber nicht warum. Bei jedem der einfachen Beispiele wird dir sofort
ein Weg einfallen, wie du die gleiche Funktionalität in Nicht-OOP
genauso einfach, wenn nicht sogar noch einfacher hinbekommst. Und bis er
dir das Monstersoftwareprojekt im Detail erklärt hat (wenn er sich dazu
überhaupt die Zeit nimmt), hast du garantiert den Spaß an der
Programmiererei (nicht nur der objektorientierten) verloren.


Nein, arbeite einfach an deinen Schnittstellenfunktionen weiter und
versuche sie zu verbesern und zu verallgemeinern, und habe kein
schlechtes Gewissen, weil alle anderen OOP machen und du nicht.

> bisher drücke ich mich (erfolgreich) um dieses Thema und komme super
> zurecht.

Das ist ein sehr guter Ausgangspunkt.

> Funktion:
> senden(Schnittstelle1, "Hallo Welt");

Ich nehme an, schnittstelle1 ist eine Schnittstellennummer o.ä.

Irgendwann möchtest du der Sendefunktion noch ein paar Parameter
übergeben, wie bspw. das von Fux genannte Blocking-Flag oder ein Enum
für das zu verwendende Hanshake-Verfahren (RTS/CTS, XON/XOFF usw.).
Damit die Argumentliste der Funktion nicht immer länger wird, und da
sich die Parameter zwischen zwei /senden/-Aufrufen sowieso nur selten
ändern, beschließt du, alle Parameter in eine Struktur zu packen und
diese als ein Argument zu übergeben. Da die Schnittstellennummer auch
nichts anderes als ein Parameter ist, packst du diese gleich mit in die
Struktur.

Deine Sende-Funktion sieht jetzt also etwa so aus:

1
enum Handshake { HS_NONE, HS_RTS_CTS, HS_XON_XOFF };
2
3
struct SendeParameter {
4
  int schnittstellenNummer;
5
  bool blocking;
6
  enum Handshake handshake;
7
};
8
9
void senden(struct SendeParameter *params, const char *string) {
10
  ...
11
}
12
13
// Aufruf
14
  struct SendeParameter params = { 1, true, HS_RTS_CTS };
15
  senden(&params, "Hallo Welt");

Natürlich hast du auch eine empfangen-Funktion. Dieser wirst du
sinnvollerweise den gleichen Parametersatz übergeben. Weil du ein
ordentlicher Mensch bist, benennst du die Struktur von SendeParameter
gleich in SchnittstellenParameter um.

Irgendwann baust du in deine Schnittstellenfunktionen noch einen
FIFO-Puffer in Form eines Ringpuffers ein. Für die Pufferverwaltung
brauchst du einen Zeiger auf den Puffer selbst sowie einen Schreib- und
einen Leseindex, die zwischen zwei senden- oder empfangen-Aufrufen nicht
verloren gehen dürfen. Da du den Zeiger und das Indexpaar für jede
Schnittstelle brauchst, packst du sie einfach in die Parameterstruktur
mit hinein. Da diese jetzt mehr als nur Parameter enthält, benennst du
sie abermals um, nämlich einfach in Schnittstelle.

Mit der Struktur Schnittstelle hast du einen Datentyp geschaffen, der
alle wesentlichen Informationen über die Schnittstelle und deren
aktuellen Zustand enthält. Was liegt näher, als einen Zeiger auf diese
Struktur auch der Funktion für die Initialisierung der Schnittstelle zu
übergeben, so dass sie durch diese gleich mitinitialisiert wird.

Du wirst sicher noch ein weitere Schnittstellenfunktionen schreiben
(bspw. eine, die die aktuelle Anzahl der Bytes im FIFO-Puffer liefert).
Auch diesen neuen Funktionen übergibst du in bewährter Weise die
Struktur als erstes Argument, denn Kontinuität ist auch in
Computerprogrammen eine anzustrebende Eigenschaft.

Irgendwann wirst du auf die Idee kommen, ähnliche Funktionen auch für
die SPI-Schittstelle zu schreiben. Kein Problem, du erstellst einfach
eine Kopie aller Funktionen, passt ihren Inhalt etwas an und benennst
die Funktionen um, um zwischen den beiden Schnittstellentypen
unterscheiden zu können:

1
Alter Name   Neuer Name       Neuer Name
2
             für UART         für SPI
3
––––––––––––––––––––––––––––––––––––––––––
4
senden       uartSenden       spiSenden
5
empfangen    uartEmpfangen    spiEmpfangen
6
...          ...              ...
7
––––––––––––––––––––––––––––––––––––––––––

Kaum hast du das getan, fallen dir zwei Dinge negativ auf:

- Von dem kopierten Quellcode sind große Teile unverändert geblieben,
  bspw. der gesamten FIFO-Pufferverwaltungscode. Tatsächlich geändert
  hast du nur die Initialisierung der Hardware und den Code für das
  Senden und Empfangen einzelner Bytes. Der ganze Rest liegt jetzt
  dummerweise doppelt im Speicher.

- Wegen der Namensänderungen musst du die Namen zusätzlich auch bei
  jedem Aufruf ändern.

Nach kurzer Überlegung kommt dir eine bessere Idee: Du machst die letzte
Aktion wieder rückgängig und baust stattdessen in die Intialisierungs-,
die Sende- und die Empfangsfunktion genau an den Stellen, wo UART- bzw.
SPI-spezifischer Code ausgeführt wird, jeweils eine Verzweigung ein.

Den Schnittstellentyp (UART oder SPI) schreibst du als Enum in die
Schnittstellenstruktur. Den gewünschten Schnittstellentyp übergibst du
anfangs der Intialisierungsfunktion, die ihn in die Struktur einträgt,
danach rufst du nur noch senden und empfangen auf ohne dich um den
Typ weiter kümmern zu müssen.

Damit kannst du sogar ein Programm mit nur einer einzigen kleinen
Änderung von UART- auf SPI-Kommunikation umstellen: Du musst lediglich
das entsprechende Argument beim Aufruf der Initialisierungsfunktion
ändern. Und das geht sogar zur Laufzeit.

Etwas weiter in die Zukunft denkend nimmst du eine Switch- anstelle der
If-Abfrage, um das Ganze künftig auf drei und mehr Schnittstellentypen
erweitern zu können.

Da mit jedem neuen Schnittstellentyp die einzelnen Funktionen immer
länger werden, beschließt du, die schnittstellenspezifischen
Programmteile in die separaten Funktionen

1
uartInitHW  uartSendeByte  uartEmpfangeByte
2
 spiInitHW   spiSendeByte   spiEmpfangeByte

auszulagern und diese aus init, senden und empfangen per
Funktionszeiger aufzurufen. Für jeden Schnittstellentyp packst du die
drei Funktionszeiger in eine Struktur. Dann legst du ein Array an, das
für jeden Schnittstellentyp eine solche Struktur enthält. An den
Stellen, wo vorher noch die Unterscheidung mit den If- bzw.
Switch-Abfragen gemacht wurde, steht jetzt ein Zugriff auf das Array mit
den Funktionszeigerstrukturen und ein anschließender Funktionsaufruf
über einen dieser Funktionszeiger.

Um weitere Schnittstellentypen hinzuzufügen, brauchst du jetzt nur noch
folgende Dinge zu schreiben:

- die drei schnittstellenspezifischen Funktionen

- einen weiteren Eintrag in das Array mit den Funktionszeigerstrukturen

Die Funktionen senden, empfangen usw. brauchst du dazu überhaupt
nicht mehr anzufassen.

"Ist das nicht supercool?", wirst du dann sagen und nach diesem Erfolg
erst recht keinen Sinn mehr darin sehen, auf eine neues Paradigma wie
OOP umzusteigen.

Aber ohne es vielleicht bemerkt zu haben, steckst du bereits metertief
in der OOP drin.

Hoffentlich wird dies einer deiner Bekannten, der sich deinen Code
vielleicht einmal anschaut, erkennen und dir ein C++-Buch vorbeibringen.
Dort wirst du einen Aha-Effekt nach dem anderen erleben: Für vieles von
dem, was du in C unwissentlich objektorientiert programmiert hast, gibt
es in C++ eine knackigere Syntax (so genannten syntaktischen Zucker).
Das ganze Gedöns mit den Enums für die Schnittstellentypen und dem Array
mit den Funktionszeigerstrukturen übernimmt vollständig der Compiler für
dich.

Begeistert von diesen Dingen wirst du das Buch zu Ende lesen und noch
viele weitere Dinge finden, die in C++ leichter oder allgemeingültiger
zu schreiben sind als in C. Wenn du bspw. in C schon mit langen und
komplizierten Makros gearbeitet hast, wirst du feststellen, dass man die
entsprechenden Aufgabenstellungen in vielen Fällen sehr viel eleganter
durch so genannte Templates lösen kann.

1
Fazit: Vergiss erst einmal die OOP, programmiere einfach weiter mit
2
Begeisterung in C, der Rest kommt von selber.


BTW: Ich selbst bin nach ein paar Frusterlebnissen mit "erzwungenem" C++
auf ähnliche Weise zu "gemochtem" C++ gelangt.

Noch davor, während meines Studiums, wollte ich mir einen "Ruck" zur
funktionalen Programmierung (wieder ein anderes Paradigma) in Form von
Lisp geben, habe aber das Thema ziemlich bald wieder beiseite gelegt,
weil ich mich wie du gefragt habe: Warum das Ganze, was habe ich davon?
Man kann doch auch alles genauso gut in C oder einer Skriptsprache
machen.

Nachdem ich sehr viel später (und lange nach meiner Anfreundung mit der
OOP) festgestellt habe, dass meine (ebenfalls objektorientierten)
Python-Programme zunehmend Konstrukte der funktionalen Programmierung
enthalten (nicht weil ich funktional programmieren wollte, sondern weil
der Programmcode damit prägnanter und übersichtlicher aussah und ich
logische Fehler leichter entdecken konnte), habe ich angefangen, mich in
"richtige" funktionale Programmiersprachen einzuarbeiten. Und jetzt
macht es im Gegensatz zu den früheren Versuchen auch richtig Spaß.

1
Fazit 2 (die Verallgemeinerung von Fazit 1): Man sollte nicht zwanghaft
2
jedem Trend hinterherlaufen. Wenn der Trend wirklich gut ist, stößt man
3
früher oder später von selber und ganz zwanglos darauf.

von Konrad S. (maybee)


Lesenswert?

@yalu
Bester Beitrag des Jahres!

von res (Gast)


Lesenswert?

Das war eine sehr ausführliche und besänftigende Antwort für den 
Fragesteller, der offensichtlich bisher noch nicht vor der Bewältigung 
größerer Softwareprojekte stand.

Bei einer ernsthaften Diskussion - die in diesem Thread wahrscheinlich 
weder angebracht noch erwünscht ist - wäre aber anzumerken, daß die 
Geschichte der technischen Entwicklung (und nicht nur diese) gezeigt 
hat, daß es erheblich effizienter ist, auf das bereits vorhandene Wissen 
und die Erkenntnisse anderer kompetenter Menschen aufzusetzen. Wollte 
jeder jede sinnvolle Entwicklung selber bei Null beginnend 
nachvollziehen, würden wir wohl heute eher am Lagerfeuer Pfeile 
schnitzen als per elektronischer Kommunikation zu diskutieren.

von O. (Gast)


Lesenswert?

OOP ist eine Mode, die schon eine Weile lang anhält.
Manch einer hat da früher drauf geschworen und ist froh, wieder
davon geheilt geworden zu sein. ;-)

Für manche Bereiche ist OOP aber auch gut geeignet,
für GUI-Progarammierung zum Beispiel.

Auch manche komplexe Problematik lässt sich mit OOP durchaus gut 
abhandeln, nur der Hype ist reichlich übertrieben. Vieles wird auch sehr 
bloatig durch OOP.

Funktionale Programmierung halte ich für wesentlich besser geeignet für 
komplexe Software, besonders wenn die eingesetzten Programmiersprachen 
starke Typsysteme haben (OCaml, Haskell).

von qwewqeqwe (Gast)


Lesenswert?

O. schrieb:
> Auch manche komplexe Problematik lässt sich mit OOP durchaus gut
> abhandeln, nur der Hype ist reichlich übertrieben.

Da ist gar nichts dran übertrieben oder gehyped. Gute Konzepte setzen 
sich durch, das war in der SE schon immer so. Für kleine Programme 
braucht man OOP natürlich nicht. Und es gibt auch Software, da 
funktioniert OOP nicht. In 95% aller Fälle ist OOP aber sehr gut 
geeignet. Ich kenne kaum Software abseits der (E-)Technik, die nicht mit 
OOP arbeiten, und das zurecht. Wer sein lebenlang mit C gearbeitet hat 
kann oder will das wohl einfach nur nicht verstehen. Ich habe auch sehr 
lange gebraucht, um zu erkennen das ich bspw. mit C# - das in meinen 
Augen den OOP-Ansatz in Vollendung verfolgt - viel schneller gute 
Software entwickeln kann als in C oder C++. Das ist einfach so. Wer in 
privaten Projekten abseits von Microcontroller Spielerreien oder 
OpenSource Kernelentwicklung noch C einsetzt, hat in meinen Augen 
einfach nur ein Rad ab.

von Möhre (Gast)


Lesenswert?

Wieso Objektorientiert?
Ich habe vor Jahrhunderten gelernt, dass objektorientiert 
kleingeschrieben werden müsste, weil es ein Adjektiv ist. Aber das 
scheint sehr sehr lange her zu sein.

von MAD (Gast)


Lesenswert?

qwewqeqwe schrieb:
> noch C einsetzt, hat in meinen Augen
> einfach nur ein Rad ab.
Das finde schlicht eine Frechheit, so eine Aussage zu machen.

Mag ja sein, dass es auf sog. Betriebssystemen wie Windoof, ein Muß
ist OOP einzusetzen. Aber der Wahrheit letzter Schluss ist es nicht.
Wir haben uns in unserer Firma mal den Spass gemacht und haben einmal in
C# und ANSI C die identische Applikation geschrieben.
Das Ergebnis war sehr ernüchternd:
Die C# Anwendung war von der Codesize (Compilat) 40% größer als die ANSI 
C Anwendung.
Was im ersten Moment nichts zu sagen hat.
Aber bei der Performance war die ANSI C Anwendung 20% performanter. Dies 
betraf die GUI und Berechnungen.
Von der Ladezeit ganz zu schweigen.

Sicher gibt es Anwendungen bei denen OOP Vorteile hat.
Aber allgemein zu sagen, dass C Müll ist, ist nicht korrekt.

Wusstet ihr eigentlich, dass schon Anfang der 70er IBM auf der /370 OO 
programmiert hat?

Und man muss nicht alles mitmachen, was einem Mickysoft vor die Füße 
schmeißt.

von Herr werfe Hirn (Gast)


Lesenswert?

MAD (Gast) schrieb:

qwewqeqwe schrieb:
>> noch C einsetzt, hat in meinen Augen
>> einfach nur ein Rad ab.
> Das finde schlicht eine Frechheit, so eine Aussage zu machen.

> Mag ja sein, dass es auf sog. Betriebssystemen wie Windoof, ein Muß
> ist OOP einzusetzen.

OOP ein "Muß" für Windows? Wie kommst du denn darauf? Das Windows-OS 
selber, d.h. die Anwender-Applikationsschnittstelle das sog. Win32-API 
ist NICHT objektorientiert. Die kannst du auch heute noch mit ganz 
stink-ordinärem C-Code anprogrammieren ("Methode" Charles Petzold). C# 
macht unter der Haube auch nichts anderes als Win-API Funktionen 
aufzurufen. Auch wenn C# selber mit Objekten hantiert (jedenfalls darauf 
ausgelegt ist), die der Anwender sich baut und anschließend instanziert. 
OOP gab es vergangentlich (und gibt es noch immer) in Windows auch mit 
Hilfe der seit Jahren vorhandenen Klassenbibliothek MFC (Microsoft 
Foundation Classes), die mal ins Leben gerufen wurde, um C++ 
Software-Systeme in OOP unter Windows realisieren zu können. Aber auch 
MFC-Code ruft - wenn das OOP C++ Programm einmal kompiliert und 
gestartet wurde - ihrerseits nur wieder die bekannten Win32-API 
Funktionen auf. Ganz genau so als wenn sie aus einem prozeduralen 
C-Programm kämen.

von Kit Falter (Gast)


Lesenswert?

Herr werfe Hirn schrieb:
> OOP ein "Muß" für Windows? Wie kommst du denn darauf? Das Windows-OS
> selber, d.h. die Anwender-Applikationsschnittstelle das sog. Win32-API
> ist NICHT objektorientiert.

Bis Windows 7 mag das gestimmt haben. Seit Windows 8 ist die Winapi aber 
auch objektorientiert.

von Borislav B. (boris_b)


Lesenswert?

MAD schrieb:
> Das Ergebnis war sehr ernüchternd:
> Die C# Anwendung war von der Codesize (Compilat) 40% größer als die ANSI
> C Anwendung.
> Was im ersten Moment nichts zu sagen hat.
> Aber bei der Performance war die ANSI C Anwendung 20% performanter. Dies
> betraf die GUI und Berechnungen.
> Von der Ladezeit ganz zu schweigen.

Solche Beispiele sind wenig Zweckdienlich. Wenn jemand keine Ahnung von 
C# oder OOP im Allgemeinen hat, bringt es natürlich auch nix "mal eben 
was auszuprobieren". Meine Erfahrungen haben nämlich genau das Gegenteil 
gezeigt.

O. schrieb:
> Funktionale Programmierung halte ich für wesentlich besser geeignet für
> komplexe Software, besonders wenn die eingesetzten Programmiersprachen
> starke Typsysteme haben (OCaml, Haskell).

Schön, dass du das so siehst. Komisch nur, dass 99% der 
Software-entwickelnden Industrie das anders sieht. Meinst du wirklich 
die würden nicht auf funktionale Sprachen setzen, wenn die so viel 
besser geeignet wären?
Ich vermute daher eher, dass du mit deiner Aussage daneben liegst.

von Yalu X. (yalu) (Moderator)


Lesenswert?

res schrieb:
> Bei einer ernsthaften Diskussion - die in diesem Thread wahrscheinlich
> weder angebracht noch erwünscht ist - wäre aber anzumerken, daß die
> Geschichte der technischen Entwicklung (und nicht nur diese) gezeigt
> hat, daß es erheblich effizienter ist, auf das bereits vorhandene Wissen
> und die Erkenntnisse anderer kompetenter Menschen aufzusetzen. Wollte
> jeder jede sinnvolle Entwicklung selber bei Null beginnend
> nachvollziehen, würden wir wohl heute eher am Lagerfeuer Pfeile
> schnitzen als per elektronischer Kommunikation zu diskutieren.

Meinem obigen Beitrag soll keineswegs dazu führen, dass jetzt jeder
Neuling die OOP von Grund auf neu erfindet. Ich bin aber der festen
Überzeugung, dass der Einstieg leichter vonstatten geht, wenn die
Motivation dazu von innen und nicht von außen kommt. Und das geschieht
im Fall des TE (und vielen anderen in der gleichen Situation) nicht
dadurch, dass man sich ohne sichtbare Notwendigkeit ein tausendseitiges
OOP- oder C++-Buch hineinzieht, sondern vielmehr schrittweise:

1. Man sammelt erst einmal in der bereits gewohnten Programmiersprache
   viel Erfahrung, insbesondere auch negative.

2. Ist man mit Motivation bei der Sache, versucht man ganz automatisch,
   die negativen Erfahrungen durch bessere Programmiertechniken in der
   gleichen Sprache kompensieren. Solche Programmiertechniken kann
   man entweder selber ausbrüten, im Code von anderen entdecken oder
   durch entsprechende Anfragen in Foren (wie z.B. diesem hier) gezeigt
   bekommen.

3. Wer mit halbwegs offenen Augen durchs Leben geht und hin und wieder
   einen Artikel über OOP liest, stellt fest, dass die eine oder andere
   der in Schitt 2 gefundenen Programmiertechniken stark in Richtung OOP
   zielt und in einer entsprechenden Programmiersprache viel leichter
   umzusetzen ist. Vielleicht wird man aber auch in der Antwort auf eine
   Forenanfrage darauf hingewiesen, dass das vorliegende Problem sehr
   viel eleganter in einer OO-Sprache gelöst werden kann.

4. Der Lernende hat bis dahin die OOP keineswegs neu erfunden, sondern
   allenfalls etwas an der Oberfläche gekratzt. Aber jetzt ist die
   Motivation da, sich mit der OOP intensiver zu beschäftigen. Jetzt
   wäre es unsinnig, neue Programmiertechniken weiterhin komplett selber
   erarbeiten zu wollen. Deswegen ist jetzt ist auch der richtige
   Zeitpunkt, die tausendseitigen Bücher in Angriff zu nehmen und
   dadurch mit dem OOP-Aufzug steil nach oben zu fahren.

   Aber erst jetzt.

Die Leute, die diesen Prozess nicht durchgemacht haben, sondern die OOP,
ohne die Erfahrungen in Punkt 1 gesammelt zu haben, im Rahmen von
Lehrveranstaltungen eingehämmert bekommen, erkennen die Vorteile der OOP
i.Allg. nicht und neigen deswegen dazu, ihren Code in völlig unsinnige
Klassenstrukturen zu pressen, nur um das Ganze objektorientiert aussehen
zu lassen.

Es kann sehr gut sein, dass Leute, die das Programmieren nicht in einer
prozeduralen, sondern gleich in einer objektorientierten Sprache lernen,
dieses Problem nicht haben. Der TE gehört aber definitiv nicht zu dieser
Gruppe.

O. schrieb:
> OOP ist eine Mode, die schon eine Weile lang anhält.

Keine Angst, sie wird auch weiterhin anhalten. Genauso wie die OOP die
strukturierte Programmierung nicht verdrängt hat, werden kommende
Programmierparadigmen die OOP nicht verdrängen. Ich kann mir allenfalls
vorstellen, dass in Aufgabendomänen, in denen es kaum natürliche und
offensichtliche Objektstrukturen gibt (davon gibt es genügend), die OOP
etwas in den Hintergrund treten wird.

> Funktionale Programmierung halte ich für wesentlich besser geeignet für
> komplexe Software, besonders wenn die eingesetzten Programmiersprachen
> starke Typsysteme haben (OCaml, Haskell).

Das wird auch ganz sicher ein Thema der nächsten Jahre sein. Schon jetzt
werden gängige imperative Programmiersprachen (bspw. Python, C#, Java,
C++11 usw.) zunehmend mit funktionalen Konstrukten gespickt. Haben die
Leute erst einmal Zucker geleckt, wagen sie irgendwann den Schritt nach
F# oder OCaml wagen, um dann noch etwas später bei Haskell o.ä. zu
landen. Zusätzlichen Auftrieb für die FP kommt von den immer mehr an
Bedeutung gewinnenden Multiprozessorsystemen, die damit leichter zu
programmieren sind.

Das alles ist aber ein langsamer, stetiger Prozess, wie auch bei der
OOP, die ja auch ein paar Jahrzehnte brauchte, um sich durchzusetzen.

Langfristig wird die imperative Programmierung (zu der auch die OOP
gehört) generell etwas an Boden verlieren (aber keineswegs aussterben),
da mit der ins Unermessliche steigenden Komplexität der Softwaresysteme
die Codeverifikation (nicht die vollautomatische, auf die wir wohl noch
eine Weile warten müssen, sondern vor allem die toolgestützte manuelle)
immer wichtiger wird. Deklarative und insbesondere funktionale Programm
lassen sich aber i.Allg. leichter und vor allem gründlicher verifizieren
als imperative.

von MaWin (Gast)


Lesenswert?

> > Auch manche komplexe Problematik lässt sich mit OOP durchaus gut
> > abhandeln, nur der Hype ist reichlich übertrieben.

> Da ist gar nichts dran übertrieben oder gehyped. Gute Konzepte setzen
> sich durch

Es gibt sehr viele Programme, denen man ansieht, daß der Anwender es mit 
dem objektorientierten übertrieben hat, und Strukturen eingeführt hat, 
die den Aufwand erhöhen, die Übersichtlichkeit reduzieren, bloss weil er 
dem Hype des objektorientierten Programmierens erlegen ist.

Du wirst zu denen gehören.

von Borislav B. (boris_b)


Lesenswert?

MaWin schrieb:
> bloss weil er
> dem Hype des objektorientierten Programmierens erlegen ist.

Das ist kein Hype, sondern Evolution.

von Alexander T. (Firma: Arge f. t. abgeh. Technologie) (atat)


Lesenswert?

Hallo Ovo,

Ovo schrieb:

> Programmierung anzufangen, bisher drücke ich mich (erfolgreich) um
> dieses Thema und komme super zurecht.

Es mag durchaus sein, dass für deine Anwendungen OOP nicht geeignet oder 
notwendig ist. Wenn das der Grund für's Rumdrücken ist, dann ist das ein 
guter Grund.

OOP kann einem bei vielen, vor allem komplexeren Problemstellungen aber 
sehr helfen, einen klaren Kopf zu behalten. Ein Beispiel: Die Vererbung 
hilft dir, bei verwandten Klassen die gleichen Methoden zu haben. Das 
erspart dir einiges an Koordinationsarbeit und Kurzzeitgedächtnis.

OOP ist ein Werkzeug, keine Religion.

Ein tieferer Blick in die OOP zwecks legaler Bewusstseinserweiterung ist 
auf jeden Fall lohnenswert.

von Stefan R. (srand)


Lesenswert?

MAD schrieb:
> Windoof

Und schon hast du dich von jeglicher ernsthafter Diskussion 
disqualifiziert. Glückwunsch!

von ... (Gast)


Lesenswert?

Weil hier von MFC dir Rede war. MFC ist das beste Beispiel dafür was 
dabei raus kommt, wenn man C Programmierer zwingt, mal schnell ein 
Framework in C++ zu entwickeln, die aber gar keine Ahnung von 
objektorientierter  Programmierung und C++ haben.

An alle OOP-Ablehner: versucht doch mal ein Ringpuffer zu programmieren, 
der mehrfach im Programm verwendet werden kann und das auch noch mit 
verschiedenen Datentypen. Spätestens dann sollte auch dem letzten klar 
werden, warum OOP und templates erfunden wurden.

von res (Gast)


Lesenswert?

Ich stimme Dir zu, daß es befriedigender und freudespendender sein kann, 
durch eigene Erfahrungen Wissen zu erlangen.
Es erfordert nur erheblich mehr Zeit.

Es hängt dabei natürlich von der eigenen Zielsetzung und den Aufgaben 
ab, ob man etwa nur aus persönlicher Neugier mal ein Programm schreiben 
will, oder vielleicht sogar beruflich Software-Entwicklung betreiben 
will.

Bezogen auf das Thema OOP würde man beispielsweise durch die 
Bereitschaft, sich dem aktuellen Wissenstand theoretisch zu nähern, 
viele Fehler vermeiden können, die sich in den vergangenen Jahren im 
Überschwang der ersten Begeisterung gezeigt haben. (Übertriebene 
Vererbungshierarchien statt Aggregation, Verdammung von "Non-member 
functions" u.v.m.)

Möglicherweise kommt man auch über den "steinigen" Weg zu einem 
sinnvollen (nicht: "aus Prinzip ist alles ein Objekt") Einsatz moderner 
Methoden der Software-Entwicklung unter Verwendung der jeweils passenden 
Werkzeuge.
Die Zurkenntnisnahme der zur Verfügung stehenden Erfahrungen ist dabei 
aber sicher hilfreich.

von ewqeqweqweq (Gast)


Lesenswert?

MAD schrieb:
> Mag ja sein, dass es auf sog. Betriebssystemen wie Windoof, ein Muß
> ist OOP einzusetzen.

So ein Schmarn.
Erstens ist es kein muss, zweitens: Auch unter Linux ist der OOP Ansatz 
mehr als verbreitet. Fast jede Anwendersoftware und Spiele sowieso bauen 
auf OOP. Der Nachfolger von XServer - Wayland - setzt deswegen auf C++ 
statt auf C. Selbst die Programme die C einsetzen, benutzen dazu einen 
Pseudo-OOP Ansatz. Siehe z. B. Gnome was ja bekanntlich auf GTK+ basiert 
und dazu sein eigene Art Framework bereitstellt.

MAD schrieb:
> Aber bei der Performance war die ANSI C Anwendung 20% performanter. Dies
> betraf die GUI und Berechnungen.
> Von der Ladezeit ganz zu schweigen.

Das sind private Spielerreien ohne wirklich relevante Aussagekraft. Wer 
Anwendersoftware für halbwegs aktuelle PC's und Systeme schreibt, den 
bringen die angeblichen 20% so gut wie gar nichts - weil sie außer im 
Benchmark - wenn überhaupt - nicht bemerkbar sind. Selbst Java 
Anwendungen laufen performant genug um nicht auf C zu setzen.

MAD schrieb:
> Aber allgemein zu sagen, dass C Müll ist, ist nicht korrekt.

Ich sage nicht das C Müll ist, sondern das es bescheuert ist C - vor 
allem in privaten Projekten - einzusetzen wenn es Aufgrund der 
Hardwarebedingungen kein Muss ist.

Das kannst du meinetwegen als Frechheit betiteln. Wenn jemand seinen 
Rasen mit eine Sense mäht statt mit einem Rasenmäher würdest du aber die 
selbe Aussage treffen.

von Dieser S. (Gast)


Lesenswert?

Es gibt doch praktisch kaum eine Software mehr unter Linux, abgesehen 
vom Kern in der Systemprogrammierung, die nicht mit OOP arbeitet. 
Entweder es ist in C++ geschrieben oder wenn in C dann mit GTK+.

von Konrad S. (maybee)


Lesenswert?

Alexander T.-Z. schrieb:
> OOP ist ein Werkzeug, keine Religion.

Meinst du? Es gibt doch schließlich OOP-Handwerker und OOP-Prediger?

Dieser S. schrieb:
> Es gibt doch praktisch kaum eine Software mehr unter Linux, abgesehen
> vom Kern in der Systemprogrammierung, die nicht mit OOP arbeitet.
> Entweder es ist in C++ geschrieben oder wenn in C dann mit GTK+.

Ich muss dir leider mitteilen, dass auf meinem Rechner von den 1389 
Executables in /bin und /usr/bin kein einziges ein C++-Programm ist. 
Sorry!

von Dieser S. (Gast)


Lesenswert?

Konrad S. schrieb:
> Alexander T.-Z. schrieb:
>> OOP ist ein Werkzeug, keine Religion.
>
> Meinst du? Es gibt doch schließlich OOP-Handwerker und OOP-Prediger?
>
> Dieser S. schrieb:
>> Es gibt doch praktisch kaum eine Software mehr unter Linux, abgesehen
>> vom Kern in der Systemprogrammierung, die nicht mit OOP arbeitet.
>> Entweder es ist in C++ geschrieben oder wenn in C dann mit GTK+.
>
> Ich muss dir leider mitteilen, dass auf meinem Rechner von den 1389
> Executables in /bin und /usr/bin kein einziges ein C++-Programm ist.
> Sorry!

Installiert man sich heutzutage einen Linux-Arbeitsrechner, sind immer 
OOP Anwendungen dabei. Und wenn es kein C++ ist dann sinds in C 
geschriebene auf GTK+ basierende Programme. Sorry!

von Konrad S. (maybee)


Lesenswert?

@Dieser S.
Klar gibt es da OOP-Anwendungen. Dann zähl mal. Bin gespannt, viewiele 
du findest. Und setz das ins Verhältnis zu den nicht OOP-Anwendungen. Da 
wirst du bei deiner Aussage deutliche Abstriche machen müssen.

von Klaus W. (mfgkw)


Lesenswert?

Konrad S. schrieb:
> Und setz das ins Verhältnis zu den nicht OOP-Anwendungen.

Blödsinnige Aussage.

Nachdem OO bei großen Programmen sinn macht, es aber viele kleine und 
deutlich weniger große gibt, ist die nackte Anzahl ein unsinniger Wert.

von Jeje (Gast)


Lesenswert?

Konrad S. schrieb:
> @Dieser S.
> Klar gibt es da OOP-Anwendungen. Dann zähl mal. Bin gespannt, viewiele
> du findest. Und setz das ins Verhältnis zu den nicht OOP-Anwendungen. Da
> wirst du bei deiner Aussage deutliche Abstriche machen müssen.

Wir reden hier die ganze Zeit von OOP Anwendungen für Endanwender. Das 
Systemprogramme da nicht zugehören ist wohl logisch oder? Obwohl Gnome 
und KDE bspw. auch OOP benutzen :) . . .

Nenn mir doch mal ein paar große Programme für Endanwender in Linux, die 
kein OOP benutzen. Gimp, LibreOffice, FileZilla, Thunderbird, Firefox. 
Ja selbst Anjuta und KDevelop. Alles Programme die auf OOP setzen. Bin 
gespannt.

von ... (Gast)


Lesenswert?

Jetzt wirds aber albern. Die meisten Systemprogramme unter Linux sind 
doch zu einer Zeit entstanden, als es noch gar kein C++ gab.

von MaWin (Gast)


Lesenswert?

> Nachdem OO bei großen Programmen sinn macht

Nun widersprichst du aber all den Verfechtern hier,
die meinen, OOP macht immer Sinn, bei jedem Programm
zumindest bei jedem Programm für ein GUI.

Ja ja, die Beliebigkeit der Behauptungen.

> von MFC mag man halten was man will.

Aha, wenn dir die Schlüsse nicht gefallen, dann zieht man mal eben die 
Aussagekraft in Zweifel.

> Aber mit .net kriegt man eine GUI
> sicherlich leichter hin als direkt auf der Windows C-Api.

Schönes Beispiel, denn eines der ganz Wenigen, bei denen ein Programm 
nicht anhängig von Zeit und Historie und Zufall in einem System 
geschrieben wurde, sondern zwei quasi funktionsgleiche Programme, 
PaintShop und Paint.NET, welches eine fast exakte Kopie von PSP4 ist, 
sich gegenüberstehen, das eine auf WinAPI, das andere mit DotNET 
erstellt, und der Vergleich geht 100 Prozent zu Gunsten von PaintShop 
aus. Wie man beispielsweise daran sieht, daß man bei DotNET einfach man 
die gradweise Drehung des Bildes weggelassen hat, weil man nicht in der 
Lage war, ihn zu realisieren.

von Konrad S. (maybee)


Lesenswert?

@Jeje
Mein gerade laufender Firefox bindet 162 Libraries ein. Davon sind 154 
C-Libraries. Soviel dazu.

von cppler (Gast)


Lesenswert?

Immer wieder fanzinierend wie ein Programmierparadigma gegen ein anderes 
in "Stellung" gebracht wird.
Man kann auch hingehen und für jedes seiner eigenen Probleme jeweils 
eine eigene Programmiersprache erstellen die genau das Problem 
beschreibt und damit löst.
Wer nicht verstanden hat worin die Vorteile von Kapselung und Vererbung 
bestehen kann nicht darüber urteilen ob es "besser" oder "unsinnig" ist.
Wenn man von Anfang an OO verfolgt hat man, wie hier schon einige 
Beispiele genannt wurden, weniger Arbeit und es ist übersichtlicher und 
somit wartbarer.
Wer natürlich lieber "Russencode" in einer einzigen Zeile ohne Kommentar 
und mit sich selbst ändernden Opcodes bevorzugt soll das tun, aber 
nachher nicht hier ankommen und verlangen das das mal einer debuggt 
weil's auf dem neuen µC nicht mehr geht da der Hersteller inzwischen die 
Register und Opcodes geändert hat ...
Und Microsoft als schlechtes Beispiel angeben ist zu einfach, wenn ich 
noch an TAPI denke wird's nur lächerlich da wurde damals (TM) im 
Developernetwork doch tatsächlich der ursprüngliche C-Code mit allen 
Fehlern 1:1 einfach gekapselt und dann als Ultima Ratio verkauft.
Man muß also zwischen Marketing und realer Programmierung unterscheiden.
Wer abstrakter vorgehen will kann sich ja mal UML ansehen, das wurde 
entwickelt um die Hausfrau von nebenan "ganz einfach" zur 
Topprogrammiererin zu machen hat aber ebenfalls viele Schwächen.
Egal wer was behauptet wenn jemand OO erlernen will hat er nachher mehr 
Vorteile als Nachteile.
Wer seinen µC aus dem FF kennt und nur diesen einen bedienen will/muß 
kann auch hardwarenah in Assembler programmieren.
Nur macht es keinen wirklichen Unterschied ob ich in Assembler, C oder 
C++ programmiere, der Compiler erledigt mir mehr Optimierungen als ich 
für verschiedene Hardware jemals selber erlernen kann.
Diese Diskussion ist daher mit der zwischen Assembler vs. Hochsprache 
identisch und genauso sinnfrei.
Wer kein OO will soll es bleiben lassen aber OO nicht herunterputzen 
weil man's entweder nicht verstanden hat oder der Meinung ist es gibt 
keine Vorteile.
Wer schonmal mehrere 10000 Zeilen Code debuggt hat wird sicherlich 
erkennen das wenn's im Objekt XYZ kracht man da viel einfacher 
Breakpoints setzen kann als wenn alles über hunderte von Zeilen verteilt 
ist.
Kapselung ist nunmal das Credo ;-)

von Jeje (Gast)


Lesenswert?

Konrad S. schrieb:
> @Jeje
> Mein gerade laufender Firefox bindet 162 Libraries ein. Davon sind 154
> C-Libraries. Soviel dazu.

Wozu? Es zeigt das OOP so gut wie in jedem Programm Sinn macht. Nichts 
für ungut :)

von ... (Gast)


Lesenswert?

@Konrad
Wie hast du rausgefunden, das es C Liberaries sind. Doch hoffentlich 
nicht über die Schnittstelle, oder?

von Konrad S. (maybee)


Lesenswert?

... schrieb:
> Wie hast du rausgefunden, das es C Liberaries sind. Doch hoffentlich
> nicht über die Schnittstelle, oder?

Wenn eine Library (auch) gegen die libstdc++.so gelinkt ist, dann werte 
ich die Library als OOP. Ist sie nur gegen die libc.so gelinkt, dann 
werte ich sie nicht als OOP. Einige in C geschriebene GUI-Libs sind 
natürlich vom Design her OOP und gehen mir mit dieser Zählweise durch 
die Lappen.

von Arc N. (arc)


Lesenswert?

MaWin schrieb:
> Wie man beispielsweise daran sieht, daß man bei DotNET einfach man
> die gradweise Drehung des Bildes weggelassen hat, weil man nicht in der
> Lage war, ihn zu realisieren.

Kann es daran liegen, dass die Funktion in Paint.NET im Menü Ebenen -> 
Rotationszoom zu finden ist und nicht im Menü Bild?
Oder liegt es daran das jemand Graphics.DrawImage aufruft und 
Graphics.RotateTransform nicht kennt bzw. bei WPF Media.Transform nicht 
kennt...

von Kreuzkrümmel (Gast)


Lesenswert?

Konrad S. schrieb:
> @Jeje
> Mein gerade laufender Firefox bindet 162 Libraries ein. Davon sind 154
> C-Libraries. Soviel dazu.

Das ändert ja nichts daran das Firefox im OOP Ansatz programmiert wurde 
augenroll . . .

von Konrad S. (maybee)


Lesenswert?

@Kreuzkrümmel
Hast du Probleme der Diskussion zu folgen? Dann lies ab hier:
Beitrag "Re: Wieso Objektorientiert?"

von Norbert (Gast)


Lesenswert?

Naja, der Thread zeigt es ja nur zu deutlich. Jeder versteht darunter 
etwas anderes und alleine beim Durchlesen der ganzen Kommentare stellt 
sich auch mir mehr und mehr die Frage, was Objektorientierung denn nun 
tatsächlich ist. Ob es sinnvoll ist und ob man es tatsächlich benötigt.

Ich persönlich würde sagen, es ist eine Modeerscheinung, die sich als 
Selbstläufer etabliert hat. Genauso wie damals eine bekannte 
Programmiersprache, die eigentlich erschaffen wurde um 
Betriebssystemkerne und Gerätetreiber zu programmieren, mit der aber 
plötzlich ganze Anwendungen geschrieben wurden. Selbst ihre Erfinder 
waren damals äußerst erstaunt darüber und konnten es nicht fassen. Aber 
sie haben den Quatsch mitgemacht denn wer verhindert schon seinen 
persönlichen Erfolg, nur weil er den Eindruck hat, dass das, was er 
persönlich geschaffen hat, plötzlich zweckentfremdet verwendet wird. 
Später wurde dann noch eine "objektorientierte" Variante dieser tollen 
Programmiersprache entwickelt (was immer das sein mag ...)

Ich hatte damals diese ganze Sache selbst miterlebt und kann auch heute 
nur noch den Kopf schütteln. Gottseidank gibts auch heute noch andere 
richtig gute Programmiersprachen. Die liegen zwar nicht so im Trend und 
sind eher was für Kenner und Liebhaber, die wissen, womit sie sich 
beschäftigen ;-)

Aber zurück zum Thema.

http://www.objektorientierung.net/

Jedem Tierchen sein Pläsierchen ;-)

Gruß, Norbert

von Borislav B. (boris_b)


Lesenswert?

Norbert schrieb:
> http://www.objektorientierung.net/

Aua. Was dieser Mensch da von sich gibt ist ja haarsträubend. Aber sehr 
unterhaltsam ^^
Erinnert mich ein bisschen an diesen Blog über die schädliche Wirkung 
von Barcodes, die aufgrund ihres wilden Schwarz-weiß-Musters böse 
Energien erzeugen sollen.

von Robert L. (lrlr)


Lesenswert?

>/www.objektorientierung.net/

bietet er/sie dann auch eine LÖSUNG ,oder werden nur die "Probleme" 
aufgezeigt?? (Jammer kann jeder ;-)



wenn man mal über den "C"-Tellerrand" schaut: z.b. auf DELPHI: 
Componenten/Controls (VCL), JCL,  Indy, Virtualtreeview, SynEdit, 
schlagmichtot....

ich GLAUBE nicht, dass es z.Z: in diesem Bereich irgend eine besser 
Lösung als Klassen/Objekte gibt
(also dort wo seine eigene Arbeit, auf der anderer aufbaut, (abgeleitete 
Klassen))...

ABER: natürlich ist das nicht DIE Lösung für alles..



>Ich persönlich würde sagen, es ist eine Modeerscheinung,

von "Interfaces" könnte man das vielleicht behaupten, deren Boom ist 
IMHO inzwischen wieder etwas abgeflacht, ..

: Bearbeitet durch User
von Rene H. (Gast)


Lesenswert?

Ich denke, dass man dem Thema nicht gerecht werden kann, wenn man nur 
die Programmierung ansieht. Schlussendlich ist "objektorientiert" auch 
noch OOA. Damit bekommt man (zum Beispiel mit UML) ein sehr mächtiges 
Werkzeug in die Hand.

Grüsse,
René

von Ovo (Gast)


Lesenswert?

Hallo,

ich habe nun lange still mitgelesen und mich über eure (zahlreichen – 
danke!) Beiträge gefreut.

Kurz vorweg, der Preis für den besten Beitrag des Jahres darf gerne an 
Yalu X. (yalu) (Moderator) gegeben werden. Einfach ein sehr guter und 
nachvollziehbarer Beitrag. Super!


Wie es weiter geht:
Nun ich denke ich bleibe, wie einige es auch vorschlugen, bei meinen 
„Leisten“. Gleichzeitig möchte ich mich nun aber, aus reinem Interesse 
und nicht der Notwendigkeit halber, mit dem Thema befassen. Denn das 
Phänomen, welches Yalu beschrieb ist korrekt. Man feilt gerne an seinen 
Funktionen herum um noch ein extra mehr mit einzubinden oder die 
Kompatibilität zu erhöhen. Ich denke, ich kann mit eine Co-Existenz 
beider Philosophien vorstellen - wer weiß, vielleicht gefällt es einem 
am Ende ja?
Am Ende kann man sicherlich immer noch entscheiden was für einen selbst 
oder den Anwendungsfall besser wäre bzw. wo die eigenen Vorlieben 
währen.


An dieser Stelle nochmal meinen Dank an alle die sich beteiligt haben.

Ovo

von old man (Gast)


Lesenswert?

Mal ein Beispiel wie sich etwas entwickeln kann:

1990 haben wir mit eine Windows-Entwickling begonnen unter Borland C++ 
mit einer Klassenbibliothek Namens "StarView". Microsoft hatte damals 
nicht mal einen C++ Compiler. Dabei ist Code entstanden der für den 
Zweck gut war und bis heute in Teilen unserer Produkte steckt. Danach 
ging's ungefähr so weiter:
Borland war irgendwann nicht mehr in der Lage das Projekt zu übersetzen. 
Interne Compilerfehler ohne dass der Hersteller darauf reagiert hat. 
Wechsel zu Zortech. Die haben auch nicht lange durchgehalten und sind 
dann glaube ich von Symantec gekauft worden. Wechsel zu Watcom und 
später dann zu Visual C. Mann waren wir froh von vornherein nicht die 
C++ StdLib verwendet zu haben und auch keine Templates u.s.w. Zu der 
Zeit ist da bei jedem Compiler noch was anderes rausgekommen. Ein 
Makrogenerator für Listen u.ä. erfüllt den selben Zweck und ging überall 
sofort. Den Quellcode von StarView haben wir dann gekauft und selbst 
weitergepflegt. Heute ist StarView (den Namen gibts so nicht mehr) ein 
Teil des Unterbaus von OpenOffice.
Später kam dann noch der gcc/g++ unter Linux, Mac und Android dazu sowie 
WxWidgets und noch ein paar fremde Libs. Und wiel die Welt so schön ist, 
musste für Teile des Codes auch noch ein PHP-, Java- und 
JavaScript(V8)-Interface dazu. Da kommt dann Freude auf bei der 
Vereinigung der Header, besonders unter Windows. Das Ende vom Lied war 
dann eine reine C-Schnittstelle die unseren gesamten objectorientierten 
Code in einfache Funktionen mit primitiven Datentypen kapselt, damit das 
unter den verschiedensten "Umweltbedingungen" pflegbar bleibt.

Was ich damit nur sagen wollte, es ist nicht immer gut die neusten 
Entwicklungen mit zu machen. Eine sinnvolle Beschränkung ist oft besser. 
Insbesondere die ganzen neueren C++ Erweiterungen sehe ich jedenfalls 
mit große Vorsicht. Will man sie einsetzen muss man sie erst mal lernen. 
Das ist ja soweit ganz ok, aber meistens werden die Exoten so selten 
benutzt, dass man jedes mal wieder neu nachlesen muss wenn mans 
verstehen will. Baue ich die ach so tolle Funktionalität aus ein ein 
paar Standardelementen zusammen ist das vielleicht nicht so schön aber 
jederzeit nachzuvollziehen ohne sich darüber Gedanke machen zu müssen 
was denn der Compiler daraus wieder alles so erzeugt.

Zur Ausgangsfrage. Das reine objektorientierte Programmieren ist wie 
wenn ich einer Funktion immer als erstes einen Pointer auf eine Struktur 
übergebe und in der Funktion selbst mit den Daten auf diesen Pointer 
arbeite. Der Code in der Funktion wird aber wesentlich übersichtlicher 
in C++ als in C. Es ist da ein Unterschied ob man schreibt:

         a=b+c oder pDaten->a=pDaten->b+pDaten->c

Das spart auch Zeit beim Tippen. Auf die Variante dass a,b und c globale 
Daten sind gehe ich hier nicht ein. Sowas kommt bei größeren Projekten 
kaum vor.

von Fux (Gast)


Lesenswert?

old man schrieb:
> Das reine objektorientierte Programmieren ist wie
> wenn ich einer Funktion immer als erstes einen Pointer auf eine Struktur
> übergebe und in der Funktion selbst mit den Daten auf diesen Pointer
> arbeite.

Du hast 20 Jahre Erfahrung in C++ und reduzierst OO auf so ein ulkiges 
Beispiel? Aua. :-(

von old man (Gast)


Lesenswert?

Fux schrieb:
> Du hast 20 Jahre Erfahrung in C++ und reduzierst OO auf so ein ulkiges
> Beispiel? Aua. :-(

Es ist ein Beispiel angepasst an die Fragestellung. Nicht mehr und nicht 
weniger. Sorry, wenn ich hier nicht anfange wissenschaftliche Vorträge 
zu halten. Die üblichen Beispiele kann sich jeder selbst aus den 
Internet suchen und was daraus machen oder nicht. Leute die auf Biegen 
und Brechen alles dem neusten Hype unterordnen kenne ich zur genüge. Das 
sind auch immer die, bei denen ein "Hello Word" aus 10MB und 20 
verschiedene Dll's besteht.

Der TE hat hier im Context von µC's gesprochen, und wenn ich C++ auf 
Controllern verwende, dann mit Sicherheit ohne C++StdLib und so. Die 
uart-Beispiele ziemlich weit oben haben als einzigen Unterschied in etwa 
das was ich als Beispiel dargestellt habe. Und wenn einer auf 
Controllern sowas wie "new Uart" verzapft, dann kann ich nur sagen: 
Schuss nicht gehört!

von Fux (Gast)


Lesenswert?

old man schrieb:
> Die uart-Beispiele ziemlich weit oben haben als einzigen Unterschied in
> etwa das was ich als Beispiel dargestellt habe.

Eben nicht. Technisch betrachtet ist das in diesen Faellen so, aber 
konzeptionell eben nicht. Und um das Konzept geht es, nicht ob der 
Pointer links oder rechts vom Methodennamen steht. Bei den obigen 
Beispielen geht es in erster Linie um Kapselung.

Nun ist mir aber klar, warum ihr mit eurem Projekt so grosse Probleme 
mit kollidierenden Headern hattet: Bei ordentlicher Kapselung und 
Verwendung von Interfaces klappt das.

von old man (Gast)


Lesenswert?

Fux schrieb:
> Nun ist mir aber klar, warum ihr mit eurem Projekt so grosse Probleme
> mit kollidierenden Headern hattet: Bei ordentlicher Kapselung und
> Verwendung von Interfaces klappt das.

Ne, schon mal ein PHP-Interface geschrieben? Oder ein asterisk-Plugin? 
PHP ist im Kern reines C. asterisk auch. Als Interface gibt's nur 
C-Funktionen. In dem Interfaceteil selbst kannst du da überhaupt keine 
C++ Header einbinden. Umgedreht schon, vorausgesetzt die Authoren dieser 
Header haben sich darüber Gedanken gemacht im C++ Umfeld included zu 
werden. Aber ganz im Ernst. Entweder du hast schon mal ein 
Php-Interface(Plugin) geschrieben und wir Unterhalten uns auf gleicher 
Augenhöhe oder du redest nicht über etwas was du nicht kennst.

von Zustandsautomat (Gast)


Lesenswert?

ich würd ganz gern (ohne arduino-software) OO auf dem AVR machen. Aber 
es gibt keinen Beispiel 'hallo-welt'-led-blink code in c++ den ich mal 
eben mit avr-g++ compilieren kann. Das läuft um darauf dan aufbauen was 
zu proggen ohne vorher mit der toolchain kämpfen zu müssen.

>a couple of months ago I started with AVR and c++. It's rather painful adventure, 
but now most of things seems to work
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453&start=all&postdays=0&postorder=asc

wow, klingt ja easy.

_extension_ typedef int __guard __attribute__((mode (_DI_)));

extern "C" int __cxa_guard_acquire(__guard *);
extern "C" void __cxa_guard_release (__guard *);
extern "C" void __cxa_guard_abort (__guard *);


klingt logisch, das brauch ich, dann kann ich auch irgendwie c++ auf avr 
machen - easy peasy.
nagut, brauch ich halt ne Menge boilerplate-code denn man halt 
copy+paste macht. total häßlich, aber wenns hilft.

Wie haben die arudino-leute eigendlich c++ lauffähig gemacht. und wenn 
das so kompliziert ist im setup, wo ist eigendlich der Unterschied 
zwischen "richtigem c++ auf avr mit viel boilerplate-code" oder gleich 
die "hihihi, du NOOB-Aurdino-software" zu nutzen?

von cppler (Gast)


Lesenswert?

old man schrieb:
> Fux schrieb:
>> Nun ist mir aber klar, warum ihr mit eurem Projekt so grosse Probleme
>> mit kollidierenden Headern hattet: Bei ordentlicher Kapselung und
>> Verwendung von Interfaces klappt das.
>
> Ne, schon mal ein PHP-Interface geschrieben? Oder ein asterisk-Plugin?
> PHP ist im Kern reines C. asterisk auch. Als Interface gibt's nur
> C-Funktionen. In dem Interfaceteil selbst kannst du da überhaupt keine
> C++ Header einbinden. Umgedreht schon, vorausgesetzt die Authoren dieser
> Header haben sich darüber Gedanken gemacht im C++ Umfeld included zu
> werden. Aber ganz im Ernst. Entweder du hast schon mal ein
> Php-Interface(Plugin) geschrieben und wir Unterhalten uns auf gleicher
> Augenhöhe oder du redest nicht über etwas was du nicht kennst.

http://www.php.net/manual/de/language.oop5.php

Und wie schon oben erwähnt ist OO ein Konzept und Mischungen kommen 
durch "dynamisches wachsen" vorhandenen Codes vor.
Wenn man von Anfang an das OO Konzept verfolgt gibt es keine 
Vermischungen und somit zu keinen Problemen.
Interfaces lassen sich auch objektorientiert programmieren siehe z.B. 
SOAP.

von old man (Gast)


Lesenswert?

cppler schrieb:
> http://www.php.net/manual/de/language.oop5.php
>
> Und wie schon oben erwähnt ist OO ein Konzept und Mischungen kommen
> durch "dynamisches wachsen" vorhandenen Codes vor.

Wir reden da aneinander vorbei. Ich meine kein in PHP geschriebenes 
Modul sondern eine Extension als .dll oder .so für php. Und da gibst nun 
mal nur C und nichts weiter. Ich bin bei meinen Ausführungen nicht auf 
die OO im allgemeinen eingegangen und das Konzept dahinter, sondern auf 
C/C++ und Controller. Und auf Projekte die so lange laufen, dass sie 
auch die übernächste Hype noch überleben. Vorausgesetzt man springt 
nicht blind auf jeden Zug auf.

> Wenn man von Anfang an das OO Konzept verfolgt gibt es keine
> Vermischungen und somit zu keinen Problemen.

Ach ja. Hast du mal überlegt dass Anfang hier 1990 heiß? Ohne Internet, 
ohne TcpIp,COM,Net,SOAP,RPC.......

Da du auch SOAP erwähnst. Hast du dir mal die Frage gestellt wieviel 
Overhead in so einer Schnittstelle wie SOAP steckt. In der 
Implementierung meine ich. Und wofür? Dafür dass ein AJAX-Request 
vielleicht 30Byte JSON-codiert zum Server schickt und als Return auch 
nur mit JSON was anfangen kann? Gefühlte 10000 Zeilen Quellcode (incl. 
xml) in mindestens 3 verschiedenen Libs die drunter liegen...
Komfort ist nicht alles. Und lesbarer wird es auch nicht zwingend.

von old man (Gast)


Lesenswert?

Die SOAP Extension von php verwendet ausschließlich reine c-Funktionen. 
So in etwa:
1
static void wsdl_soap_binding_body(sdlCtx* ctx, xmlNodePtr node, char* wsdl_soap_namespace, sdlSoapBindingFunctionBody *binding, HashTable* params)
2
{
3
  xmlNodePtr body, trav;
4
  xmlAttrPtr tmp;
5
6
  trav = node->children;
7
  while (trav != NULL) {
8
    if (node_is_equal_ex(trav, "body", wsdl_soap_namespace)) {
9
      body = trav;
10
11
      tmp = get_attribute(body->properties, "use");
12
      if (tmp && !strncmp((char*)tmp->children->content, "literal", sizeof("literal"))) {
13
        binding->use = SOAP_LITERAL;
14
      } else {
15
        binding->use = SOAP_ENCODED;
16
      }
17
18
      tmp = get_attribute(body->properties, "namespace");
19
      if (tmp) {
20
        binding->ns = estrdup((char*)tmp->children->content);
21
      }
22
23
      tmp = get_attribute(body->properties, "parts");
24
      if (tmp) {
25
        HashTable    ht;
26
        char *parts = (char*)tmp->children->content;

Klar findet man hier auch objektorientierte Ansätze in C. Darum ging es 
aber nicht. Ich wollte nur die Krux darstellen die man, wenn man größere 
Libs in C++ geschrieben hat und jetzt ein Bindig für PHP braucht. Das 
heisst:  C++ -> C -> PHP -> ...
Die Php-Programmierer finden dann wieder ihre Objekte. Aber die 
Zwischenschicht macht eben halt die Rolle Rückwärts.

von cppler (Gast)


Lesenswert?

old man schrieb:
> cppler schrieb:
>> Wenn man von Anfang an das OO Konzept verfolgt gibt es keine
>> Vermischungen und somit zu keinen Problemen.
>
> Ach ja. Hast du mal überlegt dass Anfang hier 1990 heiß? Ohne Internet,
> ohne TcpIp,COM,Net,SOAP,RPC.......
>

Da reden wir ebenfalls aneinander vorbei "Anfang" bedeutet bei einem 
NEUEN Projekt von Anfang an das OO-Modell umzusetzen.
Und TCP/IP wurde 1983 erstmals vollständig eingesetzt.
RPC gab's schon bei Mainframes und das alles hat nichts mit dem Anfang 
eines Projektes zu tun.

> Da du auch SOAP erwähnst. Hast du dir mal die Frage gestellt wieviel
> Overhead in so einer Schnittstelle wie SOAP steckt. In der
> Implementierung meine ich. Und wofür? Dafür dass ein AJAX-Request
> vielleicht 30Byte JSON-codiert zum Server schickt und als Return auch
> nur mit JSON was anfangen kann? Gefühlte 10000 Zeilen Quellcode (incl.
> xml) in mindestens 3 verschiedenen Libs die drunter liegen...
> Komfort ist nicht alles. Und lesbarer wird es auch nicht zwingend.

Da es aber als Objekt implementiert ist kann man es einfach erben und 
muß es nicht immer wieder neu kopieren oder schreiben.
Das es Fälle gibt wo etwas keinen Sinn ergibt läßt sich für alle 
Programmierparadigmen finden.
Wenn ich in der Lage bin mein Paradigma komplett durchzuziehen habe ich 
aber größere Vorteile als wenn ich nun ein propietäres Protokoll selber 
entwickeln muß das später zu unflexibel ist um den Anforderungen zu 
genügen.
Wenn ich also eine universelle Schnittstelle habe die beliebige Objekte 
überträgt, speichert oder umformt habe ich mehr Vorteile als Nachteile.
Bei µCs hat OO ebenfalls Vorteile, bei kleinen Projekten/Controllern 
macht es allerdings durchaus Sinn alles Prozedural oder gar in Assembler 
zu erledigen.
Das hat aber nichts mit OO zu tun, sondern Notwendigkeiten.

von old man (Gast)


Lesenswert?

cppler schrieb:
> Da reden wir ebenfalls aneinander vorbei "Anfang" bedeutet bei einem
> NEUEN Projekt von Anfang an das OO-Modell umzusetzen.
> Und TCP/IP wurde 1983 erstmals vollständig eingesetzt.
> RPC gab's schon bei Mainframes und das alles hat nichts mit dem Anfang
> eines Projektes zu tun.

Ich sprach vom realen Anfang unseres Projektes und nicht von irgendwas 
theoretischen. Das gabs Windows 3.0 auf dem Rechner und nix mit TcpIp. 
Da musste der Rechner neu gebootet werden wenn ein Pointer im Wald stand 
und das größte zusammenhängende Stück Speicher war 64kb groß.

> Wenn ich in der Lage bin mein Paradigma komplett durchzuziehen habe ich
> aber größere Vorteile als wenn ich nun ein propietäres Protokoll selber
> entwickeln muß das später zu unflexibel ist um den Anforderungen zu
> genügen.

laber, laber, laber...
Wenn ich solche Sätze höre wie "das OO-Modell umzusetzen". Das ist wie 
bei den Gitarristen die sich den ganzen Tag über Amps und Effekte 
ergiessen aber nur bis zu "raising sun" mitgekommen sind.

> Bei µCs hat OO ebenfalls Vorteile, bei kleinen Projekten/Controllern
> macht es allerdings durchaus Sinn alles Prozedural oder gar in Assembler
> zu erledigen.
> Das hat aber nichts mit OO zu tun, sondern Notwendigkeiten.

Auch hier lehrt die Praxis manchmal was anders. Die Architektur von 
einem kleinen AVR "mag" es wenn Daten über einen Pointer angesprochen 
werden. Das kann C und struct sein oder C++ und Klassen. Der Compiler 
erzeugt dabei oft kompakteren Code als mit globalen Variablen. Mit C++ 
wird das ganze aber deutlich lesbarer. Ob das was dabei rauskommt zu 
irgendeiner Definition aus irgendeinem Lehrbuch passt interessiert 
wirklich keinen.

von horst (Gast)


Lesenswert?

Ovo schrieb:
> Ich benutze seit Jahren meine UART Funktion und gebe sie auch gerne
> anderen die diese einfach benutzen können. Wieso sollte man diese
> Funktion nun OO umsetzen?

Um sie in einem Projekt zu verwenden, dass objektorientiert programmiert 
wird. Deine Funktion würde Methode genannt und wäre Teil einer Klasse 
anstatt Teil eines Moduls.
An der Funktion selbst würde sich kaum etwas ändern.

> x = new senden();
> x.schnittstelle(Schnittstelle1);
> x.senden("Hallo Welt");

In der Hauptroutine hättest Du soetwas wie:

SCHNITTSTELLE Schnittstelle1 = new Uart (9600, 8, 1, "Com2");
SCHNITTSTELLE Schnittstelle2 = new Usb (foo);
SCHNITTSTELLE Schnittstelle3 = new Wlan (bar);

An die Programmteile die etwas übertragen sollen übergibst Du dann die 
entsprechende Schnittstelle. In diesen Teilen brauchst Du dich dann 
nicht darum zu kümmern, über welche Schnittstelle die Informationen 
gesendet werden, beim programmieren dieser Teile weißt Du das noch nicht 
einmal.
Du verwendest dort immer:

MeineSchnittstelle.senden ("Hallo Welt");

Dadurch kannst Du die verwendeten Schnittstellen zentral verwalten und 
ändern ohne Rücksicht auf andere Programmteile nehmen zu müssen.


Natürlich geht das auch problemlos mit C. Sprachen, die 
objektorientierte Programmierung unterstützen, fördern und unterstützen 
eine derartige Vorgehensweise.

Natürlich ist diese Vorgehensweise weniger interessant, wenn das 
Programm nie auf eine andere Schnittstelle als die serielle zugreifen 
wird. Aber wenn Du Programmteile eines Tages für ein anderes Programm 
verwenden willst dann brauchst du nicht den Code auf 
"senden(Schnittstelle1,..." durchsuchen um dort eine andere 
Schnittstelle einzustellen.

> wo ist genau der Vorteil zu Prozeduralen Programmen
Keiner, Prozeduren bleiben erhalten. (In den meisten OO-Sprachen.)
Die richtige Frage wäre:
Wo ist der Vorteil zur modularen Programmierung.

von Tobias K. (t_k)


Lesenswert?

OOP ein Hype? Für GUIs? Really? _Das_fällt den meisten dazu ein? 
kopfkratz

OOP ist ein Paradigma zur SW-Entwicklung. Den meisten hier scheinen 
Typsysteme, Polymorphismus usw. da nicht einzufallen - gut, müssen Sie 
auch nicht, aber dann diskutiere ich hält nicht mit. Schuster und 
Leisten...
OOP ist nicht "besser", OOP ist "anders".

C++ ist eine multiparadigmen-Sprache, deren STL nicht wirklich viel mit 
OO zu tun hat, da sie rein auf syntaktischer/prozeduraler 
Präprozessorersetzung aufbaut. Wer jetzt schreit: Bounded Polymorphism 
mit STL? Bitte erklärts mir.

Und obwohl das hier mikrocontroller.net ist, ist dies hier das PC 
unterforum, weshalb Diskussionen über OOP und embedded AFAIK nur bedingt 
weiterführen - aber vielleicht habe ich das "PC" falsch verstanden.

OP:
>Somit kommen wir wieder zur Eingangsfrage: Ich habe schon verstanden was
>es mit Klassen, Vererbungen, etc. etc. auf sich hat, aber wo ist genau
>der Vorteil zu Prozeduralen Programmen die aus Funktionen und Statischen
>Elementen aufgebaut sind?

Das mit der Vererbung etcetc scheinst Du nur angeschaut, aber nicht 
verstanden zu haben, sonst würdest Du andere Beispiele/Fragen anführen. 
Von daher: wenn non-OOP für dich taugt, bleib dabei. "There is no Silver 
Bullet"

Tipp zum Googlen: "Cardelli Type Systems"


Viele Grüße

von Seano L. (Gast)


Lesenswert?

Tobias K. schrieb:
> OOP ein Hype? Für GUIs? Really? _Das_fällt den meisten dazu ein?
> kopfkratz

Das ist halt ein Forum für Lötkolbediener, die sind schon froh wenn der 
µC die LEDs einschaltet, bischen UART-Datengeschubse, hier mal was mit 
I2C abgefragt, dort mal was per SPI rübergeschoben, der Rest ist Port 
ein/aus Schalterei, da braucht man wirklich kein OOP und wenn dann gibts 
das meiste schon fertig als Lib., komplexe Projekte wo OOP seine 
Vorteile zeigt sehen anders aus, bei ein paar mickrigen kB RAM macht das 
nich viel Sinn und ist eher lächerlich siehe dem Arduinogeraffel.

Wenn sie dann mal was in OOP umsetzen ist das meistens grauenhaft und zu 
Recht schrott, das liegt dann aber nicht an OOP/C++ sondern an 
mangelndem Verständniss und/oder falschem Einsatzzweck

von Mark B. (markbrandis)


Lesenswert?

Schwen Gel schrieb:
> Wenn sie dann mal was in OOP umsetzen ist das meistens grauenhaft und zu
> Recht schrott, das liegt dann aber nicht an OOP/C++ sondern an
> mangelndem Verständniss und/oder falschem Einsatzzweck

So sieht's aus.

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.