Ist C ++ nicht für OOP geeignet? [geschlossen]

12

Ich habe irgendwo in einer der Antworten auf eine Frage hier gelesen (kann mich nicht erinnern, welche), dass C ++ nicht für die objektorientierte Programmierung geeignet ist. Es wurde erwähnt, dass Sie von seiner Funktion oder so etwas Gebrauch machen könnten, aber nicht im reinen OOP-Sinne (ich verstand eigentlich nicht wirklich, was die Person meinte).

Ist da etwas Wahres dran? Wenn ja warum?

gablin
quelle
5
OOP ist kein genau definierter Begriff, daher ist es ziemlich sinnlos zu diskutieren, ob C ++ geeignet ist oder nicht.
Zvrba

Antworten:

31

Wie unter Also, was * meinte * Alan Kay wirklich mit dem Begriff "objektorientiert"? , Alan Kay dachte, dass das Weitergeben von Nachrichten das wichtige Stück OOP ist, aber es ist das Stück, das "C mit Klassen" (das später zu C ++ wurde) fehlt. C ++ ist nur eine Struktur mit ein wenig Verhalten, während Objekte in Smalltalk oder Objective-C "intelligent" sind, da sie entscheiden können, was sie mit den gesendeten Nachrichten tun. Wenn ein Smalltalk-ähnliches Objekt eine Nachricht empfängt, für die es keine Implementierung hat, kann es diese träge hinzufügen, die Nachricht an ein anderes Objekt weiterleiten oder eine beliebige Aktion ausführen.

Was C ++ im Hinblick auf die Objektorientierung bietet, sind virtualMethoden und Polymorphismen, die die Art und Weise betreffen, wie diese Methoden aufgerufen werden. Wenn der Compiler einen Datentyp (oder class) mit virtuellen Methoden erkennt, erstellt er eine vtable mit einem Slot für jede virtuelle Methode. Unterklassen, die die virtuellen Methoden implementieren, platzieren ihre Implementierungen in den richtigen Slots, sodass der Clientcode lediglich wissen muss, wo in der virtuellen Tabelle der auszuführende Code zu suchen ist, anstatt ihn bis zur spezifischen Funktion aufzulösen. Was dies bedeutet , ist , dass C ++ effektiv funktioniert eine Form von mehreren Dispatch haben, obwohl sie alle im Compiler implementiert ist und ist nicht so leistungsfähig wie ein Smalltalk-artiges System.

Wenn Sie die Nachrichtenübermittlung als grundlegend für OOP ansehen, ist dies mit C ++ alles andere als einfach. OTOH Wenn Sie unter OOP das Zuordnen von Daten zu Funktionen verstehen, die auf diese Daten wirken, ist C ++ in Ordnung.

Gemeinschaft
quelle
8
+1 - aber ich dachte immer, ein Funktionsaufruf sei eine vernünftige Möglichkeit, eine Nachricht trotzdem weiterzuleiten. Es ist wahr, es ist eher eine einfache Grundlage als eine einfache Lösung für alles - aber das Muster für aktive Objekte zeigt, dass es machbar ist, von dieser Grundlage aufzubauen.
Steve314
6
so gilt dies nicht nur für C ++, aber auf Java, C #, Object Pascal, etc. Und es endet als die Windows - API - Messaging - System ist das, was Alan als die wichtigste Sache in OOP gemeint, speziell die Art und Weise sie von Delphi behandelt werden
Trinidad
@ Trinidad korrekt, außer dass C # tatsächlich die dynamische Auflösung unterstützt. Ich gehe davon aus, dass sich unsere Vorstellung von OOP im Laufe der Zeit geändert hat, um das Problem der fehlenden Weitergabe von Nachrichten zu umgehen. Zweifellos geholfen von Anbietern zu sagen, dass ihre Technologie definitiv OOP angesichts der Beweise ist ...
@ steve314 ja das ist es. In der Tat funktioniert ObjC so: Ein Nachrichtensend wird in einen Funktionsaufruf übersetzt, der die Methodenfunktion nachschlägt und aufruft. Nach meinem Verständnis ist die doppelte Zustellung wichtig.
1
@Paul: Ich verstehe nicht, dass ich nur begrenzte Erfahrung mit der Win32-API habe. Jede API, bei der Objekte von variabler Größe sind und bei der zuerst eine Routine aufgerufen werden muss, um die Größe des Objekts zu bestimmen, Speicher zuzuweisen und es erneut aufzurufen, besteht meinen Schönheitstest nicht.
David Thornley
26

Diese Art von Diskussion stört mich, weil es sich wie Exegese anhört, Leute über die Bedeutung der Heiligen Schrift oder der amerikanischen Verfassung diskutieren und darüber, was die ursprünglichen Autoren gemeint haben, als ob das, was wir denken, keine Rolle spielt.

Sehen Sie, Alan Kay war / ist ein kluger Kerl, und er hatte eine gute Idee, die sich mit einer Reihe anderer guter Ideen überschlug und deren Umsetzung in Smalltalk und anderen Sprachen fand.

Er ist nicht der Messias und OOP ist nicht das einzig wahre Programmierparadigma.

Das ist unter vielen eine gute Idee. Hat C ++ gute Ideen aus der OOP-Sicht? Natürlich tut es das.

Mike Dunlavey
quelle
8

C ++ unterstützt OOP, wenn Sie OOP so definieren, dass es Kapselung, Vererbung und Polymorphismus bedeutet.

Allerdings ist C ++ nicht wirklich zeichnen sich auf der OOP. Ein Grund dafür ist, dass der Polymorphismus häufig von Objekten abhängt, die einem Haufen zugewiesen wurden und mit denen (ungeachtet der Verwendung intelligenter Zeiger) natürlicher in einer Sprache gearbeitet werden kann, die mit Müll zusammengetragen wurde.

C ++ zeichnet sich jedoch durch generische Programmierung aus. Mit C ++ können Sie auf einfache Weise hocheffizienten, generischen Code mithilfe vorlagenbasierter funktionaler Programmiertechniken erstellen.

Charles Salvia
quelle
4

Von C ++ ausgeliehene OOP-Funktionen von Simula. Einer oder mehrere der Simula-Entwickler, IIRC, bemerkten, dass C ++ nicht das ist, was sie vorhatten.

C ++ bietet gute Werkzeuge für die Abstraktion, ist jedoch eher eine gemischte Paradigmasprache als eine objektorientierte Sprache. Die objektorientierten Funktionen sind vorhanden, Sie haben jedoch Optionen, die nicht "strikter OOP" sind.

Eines der unanständigen "Opt-outs", die Sie in C ++ erhalten, besteht darin, für Methoden eher die frühe als die späte Bindung zu verwenden. Dies ist nicht nur möglich - es ist die Standardeinstellung. In Java ist "final" verwandt, aber in gewisser Hinsicht sauberer (es gibt Absichten an, bei denen es nicht nur darum geht, einen geringfügigen Leistungsaufwand zu vermeiden), und es ist nicht die Standardeinstellung.

In gewisser Weise zeigt C ++ Anzeichen dafür, dass es sich um ein frühes Experiment handelt, das noch vorhanden ist. Trotzdem ist es immer noch ein gutes Tool mit vielen Vorteilen, die Sie in anderen OOP-Sprachen nicht bekommen.

Steve314
quelle
2
C ++ erlaubt nicht-OOP und C ++ erlaubt OOP, für einige Sprachen muss OOP erlaubt sein, daher ist C ++ eine OO-Sprache.
Trinidad
1
Ich glaube, Alan Kay von Smalltalk sagte, dass C ++ nicht das war, was er im Sinn hatte, als er den Begriff "objektorientiert" prägte. Da C ++ als "C mit Klassen" begann, eine Transplantation von Simula-Klassen auf C, und nie eine saubere Pause machte, ist es kein Wunder, dass es wie ein frühes Experiment aussieht.
David Thornley
1
@Trinidad: ANY Sprache OOP ermöglicht. Ich habe in C eine Menge netten OO-Code gesehen. Ja, es ist schmerzhaft, alle virtuellen Methodentabellen von Hand zu definieren, aber die Sprache erlaubt es eindeutig .
Jan Hudec
4

Das Erzwingen, dass alles Teil einer Klasse ist, führt nicht unbedingt zu großartigem OO-Code.

Bitten Sie einen schlechten prozeduralen Programmierer, Java zu programmieren, und er wird möglicherweise irgendwo eine Klasse belegen, ihr eine statische Hauptmethode geben und 1000 Codezeilen hineinstecken. Ich weiß, dass ich es gesehen habe.

Java hat eine switch-Anweisung. Ich habe switch( type ) { case typeA: bundles_of_code; break; case typeB: bundles_of_other_code; break }usw. sowohl in C ++ als auch in Java-Code gesehen.

C ++ unterstützt viele OO-Konzepte, aber sein Standard ist nicht von ihm definiert, aber ich denke, viel hängt davon ab, was Ihr Ziel ist.

Die wichtigste "schlechte" Semantik in C ++ ist das Kopieren von Klassen, wodurch ein Objekt in ein anderes transformiert wird. Sie können dies deaktivieren, aber dann können Sie keine Funktion zurückgeben. Glücklicherweise wird dies in C ++ 0x behoben.

Goldesel
quelle
3

Bei OOP geht es nicht nur darum, sicherzustellen, dass alles von einer Klasse ist oder in einer Klasse ist. Es ist durchaus möglich, Nicht-OO-Code in einer "rein OO" -Sprache zu schreiben. Zum Beispiel wird "main" oft als globale Funktion bezeichnet, aber eine Klasse nur zu erfinden, um eine statische main-Methode zu enthalten, ist genauso, als wäre sie nicht OO.

C ++ funktioniert am besten mit einer Mischung aus verschiedenen Dingen. Das sollte nicht überraschen, denn so funktionieren die meisten guten Dinge am besten. Oft ist OOP eines dieser sehr nützlichen Werkzeuge.

Fred Nurk
quelle
2

C ++ kann für OOP verwendet werden, ist aber nicht so 'rein' wie Smalltalk. In C ++ können Sie auch Nicht-OOP ausführen, wovon die Leute möglicherweise sprechen.

Craig
quelle
2

Obwohl ich mit dem Gefühl nicht einverstanden bin, ist es wahr, dass C ++ 's Typsystem kein reines OOP ist - nicht "alles ist ein Objekt". Zahlen (insbesondere) können nicht so einfach erweitert werden, wie dies beispielsweise in Smalltalk der Fall ist. Sie können beispielsweise die Bedeutung von "2 + 2" nicht neu definieren (obwohl Sie die Bedeutung von "zwei + zwei" neu definieren könnten).

Aber was die meisten Leute wahrscheinlich meinen, ist, dass viele Leute nicht-objektorientierten Code in C ++ schreiben, aber glauben, dass sie objektorientiert sind, weil sie eine "OOP" -Sprache verwenden. Das ist nicht wahr. Aber meiner Meinung nach können Sie in Smalltalk abscheulichen Imperativ-Code schreiben und einem anständigen OOP-Design in C ++ nicht überlegen sein.

Larry OBrien
quelle
1

Alan Kays vollkommen berechtigter Einwand gegen C ++ war, dass es sich um eine Makrosprache über C handelte.

Der Begriff "Nachrichtenübergabe" ist einfach die Idee, dass Instanzen von Klassen im Speicher gehalten werden und dass sie Methoden verfügbar machen, die aufgerufen werden können. Die Nachrichtenübergabe wird in C ++ mit vtables simuliert, die Zeiger auf Funktionen enthalten.

Zu sagen, dass die Nachrichtenübergabe in C ++ nicht vorhanden ist, ist ungenau. Genauer gesagt, dass die Nachrichtenübergabe ein integraler Bestandteil anderer Sprachen wie Smalltalk und Java ist, da die Sprache ein fremdes Konstrukt nicht vorverarbeitet und es direkt auf C pfropft.

Dies ist ein hochsemantisches Argument für das Sprachdesign, von dem ich vermute, dass es etwas über das Erfahrungsniveau des Fragestellers hinausgeht.

Davon abgesehen gibt es tausend Gründe, C ++ zu hassen, und sehr wenige Gründe, es zu lieben.

Anstatt nach dem perfekten Hammer und dem perfekten Nagel zu suchen, finden Sie das perfekte Haus zum Bauen und dann die richtigen Werkzeuge ... das braucht Erfahrung.

Es ist auch wichtig zu bedenken, dass in der Systemprogrammierung, was Alan Kay befürchtet, nicht "pure OOP" ist, sondern eine Stärke von C ++. Jedem sein eigenes ...

Bobx
quelle
1
Objective C wurde ebenfalls als Makrosprache über C gestartet, ist jedoch eine objektorientierte Sprache.
Jan Hudec
1

Meiner Ansicht nach handelt es sich weniger um ein Definitionsproblem als vielmehr um ein Usability-Problem.

Objekte sind eine Abstraktion, die das Lesen, Schreiben und Begründen komplexer Programme erleichtern soll. Für einen praktischen Programmierer ist es nicht so wichtig, ob eine Sprache alle Kriterien einer bestimmten formalen Definition von "objektorientiert" erfüllt (es scheint mehrere konkurrierende zu geben!), Als ob die angebotenen Werkzeuge zum Nachdenken geeignet sind Ihr Programm in Bezug auf diese Objekte - dh tatsächlich die vermeintlichen Produktivitätsvorteile von OOP zu ernten.

In C ++ sind Objekte eine furchtbar undichte Abstraktion, die Programmierer oft dazu zwingt, sich mit unangenehmen Problemen zu befassen, die mit der Struktur dieser Objekte im Speicher zu tun haben - Probleme, die eher an die Codierung in direktem C als an andere OOP-Sprachen erinnern. Zum Beispiel bietet C ++ Frequently Questioned Answers diese Kritik (unter anderem):

Für einen Praktiker ist es sehr vorteilhaft, sich mit anderen OO-Systemen als C ++ und mit anderen OO-Definitionen als der auf besondere Weise interpretierten Dreifaltigkeit "Einkapselung, Vererbung, Polymorphismus" vertraut zu machen, wodurch C ++ als "OO" betrachtet werden kann. Beispielsweise klingt eine Behauptung, dass eine Umgebung ohne Grenzüberprüfung oder Garbage Collection keine OO-Umgebung ist, für Personen, die an C ++ gewöhnt sind, empörend. Aber aus vielen Perspektiven macht es sehr viel Sinn. Wenn jemand ein Objekt überschreiben kann, wo ist dann die "Kapselung"? Wenn das Entsorgen eines Objekts zu herabhängenden Referenzen oder zu Speicherlecks führen kann, wie ist das System "objektorientiert"? ? Was ist mit der Fähigkeit zu sagen, welche Art von Objekt sich an einem bestimmten Ort und zu einer bestimmten Zeit befindet? Sie sagen, die Software arbeitet mit Objekten - wo sind sie? Und wenn man es nicht herausfinden kann, wie soll man die Software debuggen?

C ++ ist objektorientiert, aber unangenehm und unvollständig: Die Benutzer müssen viel Aufwand betreiben, um sicherzustellen, dass sich ihre Daten tatsächlich wie "echte" Objekte und nicht wie fehlerhafte Bits verhalten . Das heißt, eine Menge Code in C ++ über seine Lebensdauer geschrieben worden, die meisten davon Gebrauch von Klassen zu machen und dynamischen Dispatch, also ist es selbstverständlich , etwas , dass Sie kann für die praktische OOP verwenden.

Alex P
quelle
-1 für die Bezugnahme auf die FQA in einer seriösen Antwort. Die FQA ist ein Nest aus Verzerrungen, Halbwahrheiten und Missverständnissen.
David Thornley
@ DavidThornley Ist das bestimmte Zitat eine Verzerrung, Halbwahrheit oder ein Missverständnis?
Alex P
Irgendwo da drin. Die Behauptung, dass eine OO-Sprache eine Grenzüberprüfung (manchmal ohnehin in C ++ - Standardcontainer integriert) und eine Garbage Collection (intelligente Zeiger sind primitive Garbage Collection) haben muss, ist erzwungen und unaufrichtig. Der Satz über eine Sprache, die es erlaubt, dass herabhängende Referenzen nicht objektorientiert sind, ist eindeutig ein Beweis von Blatant Assertion. Ich bin verwirrt über die "Fähigkeit zu sagen, welche Art von Objekt"; Der Zeigertyp gibt es für Objekte ohne virtuelles Verhalten aus, und RTTI behandelt es für Objekte mit virtuellem Verhalten.
David Thornley
@DavidThornley Der FQA Behauptung ist , dass eine nützliche OO - Sprache sollte diese Dinge hat - (? C ++ „geeignet“) , die im Einklang mit dem Wesen Frage gestellt. Ich denke, eine Behauptung über Bare-Bones-Definitionen spricht das nicht wirklich an ... "Fähigkeit zu sagen": ein häufiges Fehlerverhalten beim Zugriff auf ein Objekt, das nicht wirklich vorhanden ist, indem einem Zeiger auf nicht initialisierte oder zuvor überschriebene Daten gefolgt wird; und Ihr Programm wird diesen Müll gerne nehmen und als Daten interpretieren und dann den Müllzeigern auf andere Mülldaten folgen, bis er eine Adresse außerhalb der Grenzen erreicht oder ein schwerwiegender Fehler auftritt.
Alex P
Das Zitat deutete jedoch nachdrücklich darauf hin, dass eine Sprache ohne Grenzüberprüfung oder Garbage Collection nicht OO ist, und ignorierte die Tatsache, dass Sie diese Dinge in C ++ haben, wenn Sie möchten. Die Frage, ob eine Sprache bestimmte Fehlerklassen verhindert oder nicht (aus welchen Gründen auch immer), ist orthogonal zu der Frage, ob sie OO ist.
David Thornley
-1

Nicht umsonst hatte Graham Lee hier die meisten positiven Stimmen. Um es noch einmal zu wiederholen, es scheint, dass eine C ++ - Klasse kein Objekt in dem Sinne ist, dass sie keine Nachrichtenübergabe durchführt. Ich denke, das ist es, was die Leute sehr aufregt, wenn sie C ++ oder oop lernen. Den Leuten wird gesagt, dass objektorientiert "das" ist, und dann, dass C ++ es anders macht. Nun, C ++ hat OOP nie anders gemacht. Wenn Sie so denken, werden Sie C ++ - Klassen niemals für das schätzen, wofür sie gedacht sind, und das bedeutet, dass sie lediglich eine Verbesserung des prozeduralen Paradigmas darstellen, indem sie Abstraktion und dynamisches Verhalten einbeziehen. C ++ - Klassen sind also grundlegend prozedural, sie verbessern lediglich das prozedurale Paradigma oder sind vielmehr eine fortgeschrittenere Version einer C-Struktur.

ärgerlich_squid
quelle
Haben Sie konkrete Gründe für Ihre Argumentation? Sie scheinen Behauptungen aufzustellen und zu behaupten, dass diejenigen, die nicht einverstanden sind, sich irren müssen oder ihre Meinung ändern würden, wenn sie es anders betrachten oder vielleicht Ihre genaue Definition von OO teilen.
David Thornley
Meinetwegen. Sie können diesen Artikel lesen . Ich denke, was ich gesagt habe, ist, dass c ++ keine "objektorientierte Programmierung" im engeren Sinne von Alan Kay ist. Wenn Sie jedoch OOP als Datenstruktur mit Verhalten definieren, können Sie c ++ als OOP betrachten. In meinen Augen ist es jedoch genauer, eine c ++ - Klasse als prozedurale Programmierabstraktion einer höheren Ebene anzusehen. Eine c ++ - Klasse ist viel effizienter als ein Kay-Objekt, aber schlechter für die Parallelität. Persönlich denke ich, dass die C ++ - Klasse ein großartiges Design ist.
ärgerlich_squid
1
Danke für den Link, aber er erklärt nur, was Alan Kay gemeint hat. Außerdem stimme ich nicht zu, dass Smalltalk im Allgemeinen als die erste OO-Sprache angesehen wird, und Wikipedia stimmt mir zu, dass dies Simula war, eine der beiden Sprachen, die Stroustrup mit Classes zu C kombiniert hat. Ich bin an Ihrer Behauptung interessiert, dass eine C ++ - Klasse mehr eine prozedurale Programmierabstraktion auf höherer Ebene als eine Objektvorlage ist, aber ich verstehe immer noch nicht, warum Sie so denken.
David Thornley
Objektorientierung ist wahrscheinlich ein subjektiver Begriff, wenn wir uns darauf einigen können. Ich sehe ein Kay-Objekt jedoch als eine natürlichere Möglichkeit, Code zu entkoppeln und gleichzeitige Modularität einzuführen, da jedes Objekt eine Rolle spielt, wie Mini-Computer, die durch die Weitergabe von Nachrichten interagieren. Unter diesem Modell muss es wenig bis keinen Code "zwischen" B / C geben, die gesamte Logik des Programms kann als Zellen und Nachrichten ausgedrückt werden. Im Vergleich dazu erfordert die Verwendung von "Klassen" normalerweise einen gewissen prozeduralen Klebercode zwischen den Klassen (es fehlt eine echte Modularität), aber der Vorteil ist, dass Klassen weitaus effizienter sind.
ärgerlich_squid
-1

Steve Yegge sagte es am besten :

C ++ ist die dümmste Sprache der Welt, im wahrsten Sinne des Wortes die am wenigsten empfindsame. Es weiß nichts über sich.

Das Objektsystem in C ++ ist zur Kompilierungszeit so fest verdrahtet und fixiert, dass es sehr weit von der ursprünglichen Vorstellung von OOP entfernt ist, die unter anderem Nachrichtenübergabe, Introspektion, Reflexion, dynamisches Versenden und spätes Binden umfasst. Das einzige, was C ++ und Smalltalk gemeinsam haben, ist ein bisschen Wortschatz.

John Cromartie
quelle
Inwiefern ist C ++ die am wenigsten empfindsame Sprache? Was bedeutet es für eine Sprache, empfindungsfähig zu sein? Wenn Sie meinen, dass es keine Reflektionsfähigkeiten gibt, dann ist das durchaus üblich und bestimmt nicht, dass C ++ aus einer Menschenmenge ausgewählt wird.
David Thornley
2
Wie um alles in der Welt kannst du sagen, dass er es "am besten" gesagt hat? Ich habe keine Ahnung, was dieses zufällige Zitat bedeutet.
user16764
+1 wenn man sagt, dass diese Art von Dingen eine Menge Flak von den C ++ - basher bashers bekommen wird, muss man sagen - man kann nicht wirklich ohne Reflektion OOP, weil man nicht die Generika hat, um sich um horizontale Dinge zu kümmern ( Aspekte) - Lebenszyklus (Aktivierung, Entsorgung), generische Fehlerbehandlung, generisches Proxying, generische Serialisierung, generische Task-Parallelität - diese führen dazu, dass Ihr Code verschmutzt und SoC zerstört wird.
Vski
Vielen Dank. Ich kann nicht glauben, dass ich -3 bekam, weil ich sagte, dass eine Sprache ohne Reflexion kein gutes Beispiel für OOP ist.
John Cromartie
1
@ JohnCromartie, könnten Sie in Ihrer Antwort auf diesen Punkt näher eingehen?
Jeremy Heiler