Sollten wir Sprachfunktionen vermeiden, die C ++ bietet, Java jedoch nicht?

110

Angenommen, ich kann C ++ nur in der Umgebung des Projekts verwenden. Ist es sinnvoll, die Verwendung einiger Sprachfunktionen zu verhindern, die in C ++ enthalten sind, in Java jedoch nicht (z. B. Mehrfachvererbung, Überladung von Operatoren)?

Ich denke die Gründe sind:

  1. Da Java neuer als C ++ ist, bedeutet dies, dass das Feature nicht gut ist, wenn Java kein Feature von C ++ bereitstellt. Daher sollten wir es vermeiden, es zu verwenden.
  2. C ++ - Code mit C ++ - spezifischen Funktionen (z. B. Friend-Funktionen, Mehrfachvererbung) kann nur von C ++ - Programmierern gepflegt oder überprüft werden. Wenn wir jedoch nur C ++ wie Java schreiben (ohne C ++ - sprachspezifische Funktion), kann der Code von beiden gepflegt oder überprüft werden C ++ und Java Programmierer.
  3. Möglicherweise werden Sie eines Tages aufgefordert, den Code in Java zu konvertieren
  4. Code ohne C ++ - spezifische Funktionen kann normalerweise besser gewartet werden
  5. Für jede sprachspezifische C ++ - Funktion (z. B. Mehrfachvererbung) sollten Alternativen in Java implementiert werden. Wenn dies nicht der Fall ist, ist das Entwurfsmuster oder die Codearchitektur problematisch.

Ist das wahr?

ggrr
quelle
7
Wenn Sie sich Ihre Vorschläge ansehen, sprechen Sie von der Schaffung eines Kodierungsstandards. Die Tatsache, dass Sie einen Standard erstellen und diesem folgen, erhöht die Wartbarkeit.
Brandin
63
Soll Java-Code auch auf Features beschränkt werden, die auch in C ++ zu finden sind? Verwenden Sie also zum Beispiel kein Java volatile, keinen Zugriff für paketprivate Klassenmitglieder, keine Reflektion / Introspektion, keine Endsperren , keine überprüften Ausnahmen usw.? Die ganze Frage ergibt nicht viel Sinn ... C ++ und Java sind sich oberflächlich ähnlich, aber letztendlich sehr unterschiedliche Sprachen.
Hyde
5
Wie sollen sich Sprachen entwickeln, wenn Menschen nicht bereit sind, neue Funktionen zu nutzen? Der Zweck der neuen Funktionen ist es, Ihnen das Leben zu erleichtern, indem Sie häufig auftretende Probleme lösen. Wenn Benutzer keine neuen Funktionen verwenden, gibt es für niemanden eine Motivation, diese zu implementieren.
Matthew
72
Wenn Sie Java möchten, verwenden Sie Java. Wenn Sie C ++ verwenden, verwenden Sie C ++, keine schreckliche, verdrehte Nachahmung von Java mit C ++ - Syntax. Wenn Sie C ++ verwenden, sich aber auf Javas Funktionsumfang beschränken, haben Sie das Schlimmste aus beiden Welten.
Jerry Coffin
11
Sie wären überrascht, wie schnell die Unterschiede Sie (und hart ) beißen werden . SomeObject a = previousObject;macht ganz andere Dinge in Java und C ++. In Java wird eine Referenz kopiert, während in C ++ das Objekt kopiert wird. In Java wirken sich Änderungen an aauch auf das vorherige Objekt aus. In C ++ haben Sie zwei separate Objekte.
Clockwork-Muse

Antworten:

307

Nein, das ist traurig und furchtbar fehlgeleitet.

  • Java-Funktionen sind nicht besser als C ++ - Funktionen, insbesondere im luftleeren Raum.
  • Wenn Ihre Programmierer nicht wissen, wie man eine Funktion verwendet, bilden Sie bessere Entwickler aus oder stellen Sie sie ein. Wenn Sie Ihre Entwickler auf das Schlimmste in Ihrem Team beschränken, können Sie Ihre guten Entwickler schnell und einfach verlieren.
  • YAGNI . Lösen Sie Ihr aktuelles Problem heute und nicht den Geist eines zukünftigen Problems.
Telastyn
quelle
6
Kürzlich gab es eine Frage zu Entwicklern, die Code in einer Sprache überprüften, die sie normalerweise nicht schreiben. Ich denke, hier gilt die Weisheit: Ein guter Entwickler entdeckt viele grundlegende Fehler in nahezu jeder Sprache, aber jede Sprache hat so viele Fallstricke, dass der maximale Nutzen erzielt wird, wenn Entwickler in einer Sprache die Überprüfung durchführen. Dies gilt auch dann, wenn Ihr C ++ "nur Java-Funktionen" enthält.
CorsiKa
5
+1 Zusätzlich zu Ihrem zweiten Punkt. Das OP sollte sich die Zeit nehmen, um sich über "C ++ Best Practices" zu informieren und zu entscheiden, welche Funktionen verwendet werden sollen. Meine letzte Information über C ++ ist, dass Friend-Funktionen und Mehrfachvererbung als schlechte Praktiken gelten . Dinge wie Vorlagen und das Überladen von Operatoren sind meiner Meinung nach gute Praktiken, wenn Sie sie mit Bedacht einsetzen.
some_coder
4
@some_coder: Es geht nur darum zu wissen, wann und wo. Wenn ich richtlinienbasierte Programmierung durchführe, erbe ich von den (möglicherweise mehreren) Richtlinienklassen, um die Struktur meiner Hostklasse um die Mitglieder zu erweitern, die diese Richtlinienklassen zum Funktionieren benötigen. So funktioniert es einfach. Auch operator<<( ostream &, T const & )wird in der Regel über implementiert friend. Das ist das Problem mit pauschalen Aussagen darüber, was eine gute und was eine schlechte Sprache ist: Sie sind gute Ratschläge, außer wenn sie nicht ...
DevSolar
142

Nur weil die Syntax auf der Oberfläche ähnlich zu sein scheint, bedeutet dies nicht, dass die beiden Sprachen kompatibel sind.

1, 4 und 5 sind wirklich die gleiche Frage:

Jetzt bin ich kein Fan von C ++, aber zu sagen, dass "Code ohne C ++ - spezifische Funktionen normalerweise besser zu warten ist", ist einfach lächerlich - glauben Sie wirklich, dass Java alles richtig gemacht und alle guten Funktionen übernommen hat, während es alle schlechten ignoriert hat? Glauben Sie wirklich, dass es etwas gibt, das allgemein als "schlecht" oder "gut" zu bezeichnen ist? Wenn ja, warum haben wir dann nicht eine Sprache, die rein gut ist? Und nein, Java ist sicherlich nicht diese Sprache. Bedeutet das, dass Java und C ++ unbrauchbar sind? Natürlich nicht.

Was ist, wenn Ihre Führungskräfte entscheiden, dass Sie auf C # anstatt auf Java portieren? Nicht nur , dass C # Unterstützung zwingende Betreiber, aber es ist auch der Standard - wenn Sie vorhaben , Menschen zu verlangen , zB verwenden obj.Equals(obj2)statt obj == obj2, die Menschen gehen , Fehler machen die ganze Zeit. Auch wenn man sich nur an die Gemeinsamkeiten der beiden Sprachen hält, gibt es unterschiedliche Erwartungen , eine unterschiedliche Kultur. Wenn Sie so etwas wie if (myField == null)in C ++ machen, werden die Leute sehen, dass Sie sofort ein Anfänger sind. Wenn Sie if (null == myField)in C # verwenden, werden die Leute feststellen, dass Sie noch nicht wirklich C # -nativ sind - die Gründe, aus denen C-Entwickler gelernt haben, die "gespiegelte" Variante zu verwenden, gibt es in C # nicht mehr.

Nach Ihrer Logik hätten wir uns an Maschinencode, Assembly oder COBOL halten sollen, denn warum sollten wir jemals zu Pascal wechseln, wenn es nur neue Funktionen hinzufügt, die Ihre Programmierer lernen müssen? Warum sollten wir jemals so etwas wie SQL verwenden, wenn es nicht einmal Schleifen hat ? Warum würden wir jemals etwas anderes als SQL verwenden, wenn SQL keine Schleifen hat und X dies tut?

C ++ - Code kann von Java-Programmierern mit Sicherheit nicht verwaltet werden. Ich kann nicht verstehen, woher Sie diese Idee haben - was genau bleibt, wenn Sie C ++ nur auf die Funktionen beschränken, die genauso funktionieren wie in Java? Sie werden nicht einmal Methodenaufrufe bekommen - nicht einmal Funktionsaufrufe . Nur weil beide Sprachen geschweifte Klammern verwenden, bedeutet dies nicht, dass die Sprachen in irgendeiner Weise austauschbar sind.

Das Konvertieren von Java-ähnlichem C ++ - Code ist extrem fehleranfällig, egal was Sie tun. Es gibt einfach zu viele Unterschiede. Wenn Sie möchten, dass Ihre Anwendung in einer anderen Sprache geschrieben wird, überlegen Sie sich, wie Sie alles modularisieren können, damit Sie die Teile austauschen können, ohne das Ganze zu beschädigen. Aber am Ende, YAGNI - egal was Sie tun, es wird einen erheblichen Aufwand bedeuten, Ihren Code "bereit für die Konvertierung nach Java" zu machen. Diese Zeit wird sehr wahrscheinlich besser für das Hinzufügen oder Verbessern Ihrer Funktionen aufgewendet.

Wir verwenden verschiedene Sprachen, weil sie uns verschiedene Werkzeuge zur Lösung von Problemen bieten. Wenn Sie ausführbare Dateien benötigen, die "überall" funktionieren, entscheiden Sie sich für Java. Wenn Sie Code möchten, der "überall" kompiliert , funktioniert C ++ einwandfrei. Wenn Sie Code möchten, der einfach zu verstehen und zu analysieren ist, entscheiden Sie sich für LISP oder was auch immer. Aber eines kann ich Ihnen sagen: Das Schreiben von Code in einer Sprache, als ob Sie ihn in einer anderen schreiben würden, ist immer ein Fehler, und Sie werden darunter leiden. Ganz zu schweigen davon, dass, wenn Sie tatsächlich einen C ++ - Mitarbeiter einstellen, dieser in der Sekunde ausgeführt wird, in der er den "Java-kompatiblen" Code sieht. Und ... der Java-Typ wird dasselbe tun. Weißt du, selbst wenn ich sowohl C ++ als auch Java "kenne", würde ich wie die Hölle rennen :)

Ich musste tatsächlich an (einfachem) C-Code arbeiten, der von einem Pascal-Entwickler geschrieben wurde, der so zu denken schien wie Sie. Er verwendete #defines, um C neu zu definieren, damit es mehr wie Pascal aussieht und sich so anfühlt, zusammen mit Dingen wie "BEGIN translates to {". Das Ergebnis war ziemlich vorhersehbar - Code, den weder C noch Pascal-Entwickler verstehen können, und voller Fehler, die auf die undichte "Abstraktion" von Pascal auf C zurückzuführen sind. Und Pascal und C sind aus heutiger Sicht fast identisch . Sogar C <-> C ++ ist ein viel größerer Unterschied, und das sind immer noch Peanuts für etwas wie C ++ <-> Java.

Luaan
quelle
9
"Wenn Sie Code wollen, der einfach zu verstehen und zu analysieren ist, wählen Sie LISP oder was auch immer." Dem würde ich nicht zustimmen. Lisp ist trivial zu analysieren, aber genau aus diesem Grund - weil es in einer Zeit geschaffen wurde, in der das Wissen über Parser und die Prinzipien, die dahinter stecken, noch in den Kinderschuhen steckte das könnte möglicherweise funktionieren - man bekommt nicht viel von den syntaktischen Vorteilen moderner Sprachen. So ist es leicht zu analysieren, aber überhaupt nicht leicht zu verstehen . Es gibt einen Grund, warum die Leute es "in überflüssigen Klammern verloren" nennen.
Mason Wheeler
9
@ MasonWheeler Das ist Geschmackssache - C-Programmierer nannten es so, nicht LISPers: P. Zählen Sie die Klammern - es gibt ungefähr so ​​viele wie in einem typischen C ++ - Programm. Der wirkliche Unterschied ist ihre Position ( myFunc()gegenüber (myFunc)), und das hat einen sehr guten Grund. LISP-basierte Sprachen sind nach wie vor sehr beliebt, insbesondere bei Mathematikern und Physikern. Die Hauptsache ist, dass LISPy-Sprachen modernen C-Programmierern sehr unbekannt sind - aber das ist kaum ein Grund, es zu ignorieren. Schema, Clojure und in gewissem Maße die ML-basierten Sprachen (OCaml, F # ...) sind in der Tat sehr LISPy.
Luaan
4
@Luaan Ich kann Ihnen mit Sicherheit sagen, dass LISP in der Physik NICHT populär ist. Die beiden dominierenden Sprachen auf dem Gebiet sind FORTRAN und C ++. FORTRAN ist 'beliebt', weil so viele alte Codes darin geschrieben wurden, aber fast alle neuen Programme sind in C ++ geschrieben. Als Forschungsphysiker habe ich noch kein einziges Mal von einem LISP-Programm gehört. Um nicht zu sagen, dass sie nicht existieren, aber die Sprachen sind definitiv nicht beliebt .
James Matta
4
@Luaan Möglicherweise benötigen wir weitere Softwareentwickler. Wir brauchen definitiv keine weiteren CS-Absolventen. Das heißt, "wir brauchen mehr Bauingenieure, also brauchen wir mehr Absolventen der theoretischen Physik."
Miles Rout
4
@ user1717828 Es ist die delikaten Effekte von Vertippen zu vermeiden , if (myField == null)wie if (myField = null), die gerade fein C kompilieren / C ++, aber wahrscheinlich nicht tun , was Sie wollten. Auf der anderen Seite if (null = myField)wird ein Fehler ausgelöst, da Sie keine Konstante zuweisen können.
Wlerin
94

Ich werde Ihre Fragen der Reihe nach beantworten.

  1. Wenn Java keine Funktion von C ++ bereitstellt, bedeutet dies, dass die Funktion nicht gut ist. Daher sollten wir die Verwendung dieser Funktion verhindern.

Ja, jede Funktion, die in Java nicht vorhanden ist, ist ein Horror auf der Festplatte. Es muss von Ihrer Codebasis gebrannt werden. Diejenigen, die nicht gehorchen, werden geschnappt, ihre Seelen werden benutzt, um die RAID-Götter zu besänftigen.

  1. C ++ - Code mit C ++ - spezifischen Funktionen (z. B. Friend-Funktionen, Mehrfachvererbung) kann nur von C ++ - Programmierern gepflegt oder überprüft werden. Wenn wir jedoch nur C ++ wie Java schreiben (ohne C ++ - sprachspezifische Funktion), kann der Code von beiden gepflegt oder überprüft werden C ++ und Java Programmierer.

Wenn Sie Zweifel haben, schreiben Sie den Code für das am wenigsten kompetente Mitglied Ihres Teams. Code wird weitaus häufiger gelesen als geschrieben, und Code, der so clever wie möglich ist, ist zu clever zum Lesen. Code-Überprüfungen, die Ihre Mitarbeiter an der Rezeption nicht verstehen, sollten abgelehnt werden. Bringen Sie ihnen bei, wie sie am Wochenende in Visual Basic 2.0 programmieren, und emulieren Sie dann ihren Codierungsstil in der von Ihnen verwendeten Sprache.

  1. Möglicherweise werden Sie eines Tages aufgefordert, den Code in Java zu konvertieren

Wahr! Aber warum bei Java aufhören? Sie werden möglicherweise gebeten, den Code eines Tages in Basic, Assembler und / oder Perl umzuwandeln. Da es in jeder Sprache Perl-Interpreter gibt, schreiben Sie Ihr Programm einfach als langen Perl-String und führen Sie die Argumente in der Sprache Ihrer Wahl an.

Wenn Sie nun die Sprache ändern müssen, schreiben Sie einfach den Code um, der die Perl-Zeichenfolge umschließt.

  1. Code ohne C ++ - spezifische Funktionen kann normalerweise besser gewartet werden

Es ist wahr, dass Code, der weniger Funktionen verwendet, einfacher zu warten ist. Und da alle Sprachen einer Turing-Maschine entsprechen und eine Turing-Maschine die wenigsten Funktionen einer Programmiersprache aufweist, muss der oben genannte Perl-Interpreter tatsächlich eine Turing-Maschine (Band und alles) ausführen, die Ihr Problem löst.

  1. Für jede sprachspezifische C ++ - Funktion (z. B. Mehrfachvererbung) sollten Alternativen in Java implementiert werden. Wenn dies nicht der Fall ist, ist das Entwurfsmuster oder die Codearchitektur problematisch.

Die sprachspezifischen Funktionen von C ++ haben tatsächlich einen wertvollen Nutzen. Da es sich nicht um Java handelt, handelt es sich um Anathema, und diejenigen, die es verwenden, können als Ketzer bezeichnet werden. Wenn C ++ diese Sprachfunktionen nicht hätte, könnten Sie die nicht finden, die Sie opfern müssen. C ++ Sprachfunktionen lösen Probleme!


Schauen Sie, C ++ und Java haben unterschiedliche Fähigkeiten. Das Programmieren im Schnittpunkt von C ++ und Java führt zu Code, der die meisten Vorteile beider Sprachen zunichte gemacht hat.

Java wurde teilweise als Reaktion auf den Missbrauch von C ++ - Funktionen entwickelt. Dies bedeutet nicht, dass die Reaktion gerechtfertigt war, insbesondere Jahre später, wenn die Merkmale gereift sind.

Sie können schreckliche Dinge tun, indem Sie den Operator überladen. Aber keine Sprache kann verhindern, dass schrecklicher Code in der Sprache geschrieben wird, es sei denn, sie verhindert, dass der gesamte Code in der Sprache geschrieben wird.

Und Sie können auch sehr elegante Dinge mit Überladung des Operators tun. Einfache Dinge, wie eine komplexe Zahl oder eine Matrixklasse, die wie eine komplexe Zahl oder eine Matrix funktioniert.

Vorsicht bei der Verwendung von C ++ - Funktionen, die in Java nicht verfügbar sind, ist geboten. Nur weil Ihre aktuelle Gruppe von Entwicklern mit ihrem aktuellen Kenntnisstand ein Feature nicht versteht, bedeutet dies nicht, dass es niemals verwendet werden sollte. Nur weil Sie eine Funktion verwenden können, heißt das noch lange nicht, dass Sie dies tun sollten. In einem Java-starken Geschäft ist die Wahrscheinlichkeit jedoch größer, dass der Widerstand gegen nicht Java-ähnliche Funktionen größer ist als er sein sollte.

Die Konvertierung von Code zwischen Sprachen erfolgt am besten mit einem Umschreiben, egal wie strukturell ähnlich sie sind. Jeder Versuch, dies ohne ein solches Umschreiben zu tun, wird kläglich scheitern.

Viele C ++ - spezifische Funktionen sind Wunder für die Wartung. Mit der Option "Typ löschen" (like std::function) können Sie Hierarchien entkoppeln, wodurch Abhängigkeiten verringert werden. Intelligente Zeiger und deterministische Lebensdauern sowie RAII reduzieren die Laufzeitüberraschungen und schieben die Ressourcenkessel aus dem Weg. Schwerwiegende statische Typprüfungen bedeuten, dass der Code nicht kompiliert werden kann, anstatt zu funktionieren. Mix-Ins reduzieren die Codeduplizierung. ADL ermöglicht die ad-hoc-unabhängige Erweiterung von Schnittstellen zwischen Typhierarchien. Mit Lambda können Sie Code an der Stelle schreiben, an der er verwendet wird. Durch Weiterleiten und Verschieben werden Kopien reduziert und die nebenwirkungsfreie Programmierung wird effizienter. Das Überladen von Operatoren reduziert das Zeilenrauschen und lässt den Code mehr wie die Mathematik aussehen, die er modelliert.

Vorsicht vor der Turing Teergrube. Sie können alles in jeder Sprache implementieren (einschließlich einer rohen Turing-Maschine mit Klebeband), aber das bedeutet nicht, dass Sie das sollten . Das Emulieren von C ++ - Funktionen mit Java-ähnlichen Konstrukten in C ++ ist eine schreckliche Idee. es wird zu nicht wartbarem Code führen, den niemand lesen oder verstehen kann.

Sie können sich von Java-Designs inspirieren lassen und diese nach C ++ portieren. Ich bin ein großer Fan von Python-Sprachfunktionen und deren Implementierung in C ++, weil mir die Syntax gefällt. Das bedeutet jedoch nicht, dass ich meine Klassenmethoden als statische Methoden schreibe, die ein explizites Selbst verwenden, und dann einen Wrapper schreibe, der den nicht statischen Methodenaufruf an sie weiterleitet.

Modernes C ++ ist nicht so sehr mit der Sprache vergleichbar, die Java emuliert und verworfen hat. Lassen Sie sich nicht von den Funktionen einer Sprache einschränken. Es gibt keine "eine wahre Sprache". Erfahren Sie mehr über neue Sprachen und deren Funktionen und nehmen Sie deren Besonderheiten auf.

Yakk
quelle
1
-1, langatmig und unübersichtlich.
Djechlin
4
-1 argumentative, Strohmann-Argument
user949300
28
+1, ordnungsgemäße Dekonstruktion der gestellten Fragen und ich lachte :)
Katze
11
+1. Urkomisch, aber der Punkt bleibt. Sehr klar für Leute, die es tatsächlich lesen.
Luis Masuelli
14
"Das Programmieren im Schnittpunkt von C ++ und Java führt zu Code, der die meisten Vorteile beider Sprachen zunichte gemacht hat." Den Nagel auf den Kopf treffen! +1
Ajedi32
56

Ich werde nur Ihre Gründe beantworten:

  1. Ich verstehe nicht, wie Sie zu diesem Schluss kommen. Unterschiedliche Sprachen haben unterschiedliche Merkmale. Kommt auf Umfang, Architektur der Sprache, manchmal Vorlieben der Schöpfer und viele weitere Gründe an. Einige Merkmale einer Sprache mögen schlecht sein, aber Ihre Verallgemeinerung ist meiner Meinung nach einfach falsch.
  2. Das Schreiben von C ++ wie Java kann zu schlechterem Code führen. ZB vermeide ich heutzutage mit C ++ 11 die Verwendung von new / delete, sondern verwende gemeinsame Zeiger. In deinem Szenario würde ich mich nur auf new / delete verlassen. Wenn Ihre Programmierer nur Java verstehen, schulen Sie sie oder stellen Sie bessere ein.
  3. Wird das wahrscheinlich passieren? Warum schreibst du nicht zuerst in Java? Ich halte es im Allgemeinen für eine schlechte Idee , Programme in einer neuen Sprache von Grund auf neu zu schreiben, und Sie brauchen eine wirklich gute Begründung für ein solches Risiko.
  4. Dies ist nur eine Annahme.
  5. Hängt meiner Meinung nach stark von Ihrem Szenario oder Anwendungsfall ab.
Simon
quelle
27
Und Java-Programmierer würden das auch nicht nutzen delete.
PAULO Ebermann
8
Ich musste Speicherlecks beheben, die von Java-Programmierern verursacht wurden, die nichts davon wussten delete. Soweit ich mich erinnere, war in mindestens einem dieser Fälle auch newkeine dynamische Zuordnung ( ) erforderlich.
Ethan Kaminski
16
@EthanKaminski Ja, auf diese Weise können Sie leicht einen C ++ - Neuling ausmachen, insbesondere jemanden, der über einen Java-Hintergrund oder einen ähnlichen Hintergrund verfügt. Hör auf, für alles Neues zu verwenden, verdammt!
Luaan
1
@ PaŭloEbermann Ja, noch schlimmer.
Simon
1
"In deinem Szenario würde ich mich nur auf new / delete verlassen" - komisch, ich hätte gedacht, dass ein "Java (like) -Features only" C ++ - Idiom ausschließlich zu verwenden wäre make_shared.
Kyle Strand
26

Java verfügt über Funktionen, die C ++ nicht bietet, wie beispielsweise einen integrierten, schnellen und zuverlässigen Garbage Collector, eine Objekthierarchie mit nur einem Stamm und eine leistungsstarke Introspektion.

Die anderen Funktionen von Java sind so konzipiert, dass sie mit den exklusiven Funktionen von Java zusammenarbeiten. Viele der C ++ - Funktionen von Java können weggelassen werden, da die neuen Funktionen den Mangel ausgleichen. Beispielsweise verfügt Java nicht über stapelzugeordnete Objekte mit deterministischen Destruktoren, sondern über endgültige Blöcke (und Versuche mit Ressourcen seit Java 7) und den Garbage Collector, um diesen Mangel auszugleichen.

C ++ hat keine endgültigen Blöcke oder Speicherbereinigungen. Wenn Sie keine Destruktoren verwenden, weil sie in Java nicht vorhanden sind (ich zähle keine Finalizer), befinden Sie sich auf der C-Ebene der Ressourcenverwaltung (dh alle manuell), mit der Ausnahme, dass Sie Ihre Bereinigung nicht einmal gruppieren können in einen Bereinigungsblock, zu dem Sie gehen, weil Java auch keinen hat. Denken Sie wirklich, dass dies die Wartbarkeit verbessert?

Java hat eine übergeordnete Objekthierarchie, in der jede Klasse letztendlich von Object abgeleitet ist, und die wenigen primitiven Typen können auch automatisch in solche Klassen eingeschlossen werden. Dies ermöglicht das einmalige Schreiben von Objektcontainern, um Zeiger auf das Objekt zu speichern. Mit Java 5 wurden Generika eingeführt, die die Casts entfernen, die solche Container benötigen, aber dennoch so ziemlich denselben Code kompilieren.

C ++ hat keine solche Hierarchie. Um das Schreiben von Containern zu vereinfachen, die für mehrere Typen funktionieren, verwenden Sie Vorlagen. Hierbei handelt es sich um Entwürfe, die vom Compiler bei Bedarf für verschiedene Typen instanziiert werden. Verbieten Sie die Verwendung von Vorlagen (und Makros) und gehen Sie den C-Weg, entweder denselben Containercode für verschiedene Typen immer wieder zu schreiben oder leere Zeiger zu verwenden? (Warten Sie, Java hat keine leeren Zeiger!) Sind Sie sicher, dass dies die Wartbarkeit erhöhen würde?

Eine anständige Sprache hat eine Vielzahl von Funktionen, die zusammenarbeiten sollen. Indem Sie Features von Sprache A verbieten, weil Sprache B sie nicht hat, lähmen Sie Sprache A, weil Sie nicht gleichzeitig Features von B hinzufügen, die B zu einem zusammenhängenden Ganzen machen.

Das heißt nicht, dass Sie die zulässigen Funktionen von C ++ nicht einschränken dürfen. C ++ ist eine große, historisch gewachsene Sprache, die es dem Programmierer ermöglicht, das zu tun, was er will, und zwar in Bezug auf Sicherheit und Benutzerfreundlichkeit. Nicht alle Funktionen in ihrer ganzen Flexibilität sind erforderlich, um gute Programme zu erstellen. Es gibt viele Codierungsstandards, die die Verwendung einiger Funktionen einschränken. Zum Beispiel verbieten Googles Richtlinien meistens Mehrfachvererbung, komplexe Vorlagen und Ausnahmen (obwohl die letzte aus historischen Gründen ist). Es ist jedoch keine Funktion verboten, "weil Java sie nicht hat". Die Funktionen werden nur im Rahmen von C ++ berücksichtigt.

Sebastian Redl
quelle
27
Erfahrene C ++ - Veteranen lehnen normalerweise die Kodierungsrichtlinien von Google ab. Modernes C ++ ist viel besser, weil es genau diese Funktionen nutzt . Ja, das macht es noch anders.
Jan Hudec
17
Beachten Sie, dass C ++ keine finally-Blöcke hat, aber RAII, was in den meisten Fällen viel besser ist. Und wieder anders.
Jan Hudec
7
Java's Objectist so ziemlich ein void*für die meisten Zwecke - Trotzdem, igitt.
Quentin
1
Über die Auswahl der Funktionen hinaus geht es um Stil und Ausdrucksweise. Programme sind im Allgemeinen leichter zu lesen und zu warten, wenn sie die normalen Redewendungen für die Sprache verwenden, in der sie geschrieben wurden. Selbst wenn man einen Teil eines C ++ - Programms nur mit Java-ähnlichen Funktionen schreiben könnte, wäre das Ergebnis seltsames, gestelztes C ++.
Patricia Shanahan
2
Ich würde diese Antwort dafür begrüßen, dass ich auf dem richtigen Weg bin ("mach es nicht"), aber ich kann die Grundannahme nicht ertragen, dass Java irgendwie "fortgeschrittener" ist als C ++. C ++ nicht braucht einen Garbage Collector oder eine Single-Root - Objekthierarchie, die gleiche Art und Weise Java nicht braucht ... err ... sorry ich weiß nicht , wie der Satz zu beenden, denn ich vermisse deter Destruktoren in Java, und finallyist kein Ersatz für sie. Die beiden Sprachen unterscheiden sich nur grundlegend .
DevSolar
25

Ich habe darüber nachgedacht, ob ich eine weitere Antwort veröffentlichen soll, wenn Sie bereits eine Nummer haben, die völlig vernünftige Schlussfolgerungen zu ziehen scheint: Ihre Idee ist im Grunde eine Katastrophe, die darauf wartet, passiert zu werden. Ich denke jedoch, dass sie einige hochrelevante Gründe für diese Schlussfolgerung nicht aufgezeigt haben.

Die Unterschiede zwischen Java und C ++ gehen weit über die Details hinaus, auf die Sie sich anscheinend konzentriert haben.

Sie sprechen beispielsweise über das Verbot der Mehrfachvererbung in C ++. Zunächst möchte ich darauf hinweisen, dass hier einfach der springende Punkt fehlt. Java definiert "Interfaces" als separate Dinge von "Klassen". Eine Klasse erbt nur von einer anderen Klasse, kann jedoch eine beliebige Anzahl von Schnittstellen implementieren.

C ++ trennt die beiden Konzepte nicht auf diese Weise. Die nächstgelegene analoge C ++ zur Implementierung einer Schnittstelle in Java bietet wird von einer anderen Klasse erben. Aus diesem Grund müssen Sie wahrscheinlich in C ++ Mehrfachvererbung verwenden , um die beiden Elemente im Einklang zu halten. Sie möchten jedoch einige dieser Basisklassen in etwa auf die gleiche Weise einschränken, wie Java eine Schnittstelle im Vergleich zu einer Klasse einschränkt (dh im Wesentlichen dass es Funktionssignaturen spezifiziert, aber zumindest meistens keine Implementierungen).

Das kratzt aber kaum an der Oberfläche der wirklichen Unterschiede zwischen den beiden. In der Realität, wo Java-Code wahrscheinlich Schnittstellen und Klassen definiert, die diese Schnittstellen implementieren, ist es viel wahrscheinlicher, dass C ++ - Code einige Vorlagen definiert, die mit jeder Klasse funktionieren , die ihre Anforderungen erfüllt (nicht nur mit solchen, die speziell für die Implementierung der Schnittstelle definiert wurden (s) es spezifiziert).

Wenn Sie ehrlich gesagt Code wollen, der im Grunde genommen "Java mit C ++ - Syntax" ist, müssen Sie mit ziemlicher Sicherheit alles verbieten, was dem letzteren ähnlich ist. Sie müssen die Verwendung von Vorlagen auf ungefähr die Ebene "Container of T" beschränken, die von Java-Generika unterstützt wird. Leider führt dies zu einem C ++ - Code, der so durcheinander ist, dass niemand ihn so wie er jetzt existiert warten kann, ganz zu schweigen von der langfristigen Möglichkeit, ihn in eine andere Programmiersprache zu übersetzen.

Wenn Sie wirklich Code möchten, der in Zukunft in eine andere Sprache konvertiert werden kann, bemühen Sie sich, ihn so sauber und lesbar wie möglich zu gestalten. Das Ideal ist, Pseudocode zu schreiben und noch ausführen zu lassen. Gut geschriebene moderne C ++ - Ansätze, die das Ideal viel näher bringen als die von Ihnen vorgeschlagene Teilmenge. Egal wie Sie es schreiben, wenn Sie jemals nach Java übersetzen, müssen Sie tatsächlich den Code übersetzen, nicht nur die Syntax der einzelnen Anweisungen.

Jerry Sarg
quelle
Viele C ++ - Funktionen können auf eine Weise verwendet werden, die Java-Konzepten entspricht, und auf eine andere Weise, die dies nicht tut. Einige Teile eines Programms erfordern etwas, das außerhalb der überlappenden Teilmenge der Sprachfunktionalität liegt, und der Versuch, Teile wie "Java mit C ++ - Syntax" zu schreiben, wird zu einem fürchterlichen Durcheinander führen. Andererseits benötigen viele andere Teile des Codes möglicherweise irgendetwas außerhalb der gemeinsam genutzten Teilmenge, und der Versuch, in den gemeinsam genutzten Teilen des Codes zu bleiben, in denen es keinen zwingenden Grund gibt, außerhalb des Codes zu bleiben , kann hilfreich sein.
Supercat
Vermutlich meinen Sie, wo Sie "vielleicht brauchen" sagen, wirklich: "vielleicht nicht brauchen"? Angenommen, dann würde ich eher zustimmen.
Jerry Coffin
Jep. Wenn eine Plattform unterstützt werden muss, die Java, aber nicht C ++ unterstützt, müssen Teile des Codes mit ziemlicher Sicherheit von Grund auf neu geschrieben werden, und es spielt keine Rolle, ob diese Teile mit Java-freundlichen Techniken geschrieben wurden, da werde trotzdem umgeschrieben. Es kann jedoch möglich sein, andere Teile so zu schreiben, dass sie ohne eine vollständige Neuschreibung migriert werden können, und in einigen Fällen sind die hierfür erforderlichen zusätzlichen Kosten minimal.
Supercat
4
@supercat: OTOH, angesichts der Anzahl der Plattformen, die Java, aber nicht C ++ unterstützen, erscheint mir dies als fast vollständige Lösung bei der Suche nach einem Problem.
Jerry Coffin
Für eine Weile war die Browserunterstützung für Java-Applets besser als für C ++ - Applets. Die Browserunterstützung für JavsScript (keine Beziehung zu Java) wurde jedoch so weit verbessert, dass sie im Grunde genommen von beiden übernommen wurde.
Supercat
11

Wenn Sie Code in Sprache X schreiben, nehmen Sie sich Zeit, um die Sprache richtig zu lernen, und nutzen Sie alle Funktionen, die es bietet, um das Problem zu lösen. Schlimme Dinge passieren, wenn Sie versuchen, eine "Wort für Wort" -Übersetzung von einer Sprache in eine andere zu machen, sei es Japanisch in Englisch oder Java in C ++. Es ist weitaus besser, mit einem guten Verständnis des Problems zu beginnen und die Lösung so auszudrücken, wie es für die verwendete Sprache am natürlichsten ist.

Vor Jahren sah ich ein C-Programm ohne Einrückung und jede Anweisung begann in Spalte 7, weil der Autor des Codes ein Fortran-Programmierer war, der zufällig C verwendete. Andere Fortran-Programmierer waren nervös wegen dieser neuartigen Dinge, die Zeiger genannt wurden. Ich hatte nicht das Herz, Zeiger auf Zeiger zu erwähnen, ich glaube, sie wären sofort ohnmächtig geworden.

Stellen Sie sich vor, Sie beauftragen jemanden, der diesen Code in Zukunft verwaltet. Wenn es sich um guten C ++ - Code handelt, können Sie einen kompetenten C ++ - Entwickler einstellen, der sich zurechtfinden sollte. Wenn es sich um "Java in C ++" handelt, können weder C ++ - noch Java-Entwickler den Code leicht verstehen.

Tom Penny
quelle
7

Alle Ihre Gründe können widerlegt werden:

Wenn Java keine Funktion von C ++ bereitstellt, bedeutet dies, dass die Funktion nicht gut ist. Daher sollten wir die Verwendung dieser Funktion verhindern.

Dies bedeutet nicht, dass die Funktion nicht gut ist (keine Funktion kann von Natur aus schlecht sein). Dies bedeutet nur, dass die Funktion häufig missbraucht wurde (oder aufgrund grundlegender Konzepte wie direkter Zeiger oder Garbage Collection nicht implementiert werden konnte). Java soll per Definition einfacher und programmiererfreundlicher sein, daher sollten Features entfernt werden, die sich als leicht missbräuchlich erwiesen haben.

C ++ - Code mit C ++ - spezifischen Funktionen (z. B. Friend-Funktionen, Mehrfachvererbung) kann nur von C ++ - Programmierern gepflegt oder überprüft werden. Wenn wir jedoch nur C ++ wie Java schreiben (ohne C ++ - sprachspezifische Funktion), kann der Code von beiden gepflegt oder überprüft werden C ++ und Java Programmierer.

Oh kann es sein? Sehen wir uns den einfachsten C ++ - Code an:

int len = mystring->size();

Hoppla, es werden keine "sprachspezifischen" Funktionen verwendet, aber es ist für Java-Entwickler bereits unerreichbar! Weil Sie in Java mit "." Dereferenzieren während hier ist es "->.

Möglicherweise werden Sie eines Tages aufgefordert, den Code in Java zu konvertieren

Oder C #. Oder Haskell. Oder Python. Oder Ruby. Oder COBOL (ja, das kannst du!). Wie kannst du die Zukunft erzählen?

Code ohne C ++ - spezifische Funktionen kann normalerweise besser gewartet werden.

Genau das Gegenteil. Alle Funktionen wurden eingeführt, um die Programmierung zu vereinfachen und die Wartung zu vereinfachen. ZB: Nehmen Sie ein Programm, das auf Schwimmern läuft. Rüste es jetzt auf, um komplexe Zahlen zu verarbeiten. Bedienerüberladung zur Rettung!

Für jede sprachspezifische C ++ - Funktion (z. B. Mehrfachvererbung) sollten Alternativen in Java implementiert werden. Wenn dies nicht der Fall ist, ist das Entwurfsmuster oder die Codearchitektur problematisch.

Aber Java hat mehrere Vererbung! Es heißt "Schnittstelle". Die Java-Implementierung ist eine problematische Problemumgehung, um den gefürchteten Diamanten zu vermeiden, der dadurch entsteht, dass alles davon abgeleitet ist Object. Es wird eingeführt, interfacewelcher einzige Zweck darin besteht, etwas zu sein, von dem nicht abgeleitet wird Object. C ++ hatte dieses Problem nie - es gibt keine verbindliche gemeinsame Basis, sodass jede Klasse als Schnittstelle ohne den gefürchteten Diamanten fungieren kann.

Randnotiz: Java hat kürzlich ... konkrete Methoden in Interfaces eingeführt. Es wurde eine Funktion hinzugefügt, mit der C ++ immer ein Problem lösen musste, das es nie gab.

Sie haben auch nur sehr wenige "Dinge erwähnt, die C ++ hat, Java jedoch nicht". Einer der größten Unterschiede zwischen C ++ und Java ist die Kontrolle über das Speicherlayout. Sie können ein Array von Zeigern auf Objekte erstellen (genau wie in Java) ODER einen zusammenhängenden Speicherblock erstellen. Wenn ich mir jetzt Gedanken über eine C ++ - Funktion machen würde, die Java-Entwickler irreführen könnte, wäre etwas so Verborgenes und Feines wie dieses auf meiner Liste viel höher als offensichtlich und auf den ersten Blick erkennbar, z. B. mehrfache Vererbung oder überladene Operatoren.

Fazit: Clean Code ist Clean Code. Java oder C ++ - gleicher Unterschied. Halte es einfach. Unnötige Komplikationen sind die häufigste Ursache für fehlerhaften Code.

Agent_L
quelle
Java bietet einige Funktionen und Garantien, die in einer Sprache, die alle Funktionen von C ++ bietet, nicht unterstützt werden können. Eine Sprache kann zum Beispiel nicht das Laden dynamischer Typen und Javas gesamte Palette identitätserhaltender Besetzungen zulassen, während die in C ++ enthaltenen verallgemeinerten Formen der Mehrfachvererbung angeboten werden.
Supercat
@supercat Ich verstehe nicht, warum du das hier sagst. Die Frage bezieht sich nicht auf Java-Funktionen, die in C ++ nicht reproduziert werden können, sondern auf C ++ - Funktionen, die Java verworfen hat.
Agent_L
Mein Punkt ist, dass einige Funktionen in Java nicht in C ++ enthalten sind, sondern dass einige Funktionen von Java grundsätzlich nicht mit anderen Funktionen in C ++ kompatibel sind, sodass keine Sprache Typen haben kann, die beide unterstützen (Sprachen wie C ++ / CLI) Es gibt Typen, die C ++ - Funktionen und Typen, die Java-ish-Funktionen unterstützen, unterstützen, sie bewohnen jedoch separate Universen mit eingeschränkter Interoperabilität.
Supercat
6

Nein, Sie sollten im Allgemeinen nicht C ++ schreiben, als wäre es Java, und Sie sollten auf keinen Fall C ++ - Sprachfunktionen auslassen, die in Java nicht vorhanden sind.

Zum einen handelt es sich bei Java um Garbage Collected, und daher gibt es kein Äquivalent zum C ++ - Schlüsselwort "delete". Okay, Sie implementieren ein Programm, ohne es zu löschen, da dies nach Ihren Regeln nicht zulässig ist.

Herzlichen Glückwunsch, Sie haben jetzt ein Speicherleck;). Das ist auch nicht theoretisch - genau das habe ich in einem Open-Source-Spiel gesehen.

In ähnlicher Weise hat Java keine ähnlichen C ++ - Zeiger wie Java, wodurch viele gängige Funktionsaufrufkonventionen ausgeschlossen werden.

Es gibt Funktionen in C ++, die Sie vielleicht vermeiden sollten (siehe unten), aber "nicht in Java zu sein" ist kein guter Lackmustest.


Bessere Richtlinien wären:

  1. Schreiben Sie Code, der für Ihre Sprache, Umgebung und Tools geeignet ist.
  2. Schreiben Sie Code, den Ihr Team verstehen kann.
  3. Stellen Sie sicher, dass Ihr Team in der angegebenen Domäne kompetent ist.

Punkt (3) bedeutet, dass Sie keinen Java-Programmierer-Code in C ++ haben sollten, ohne diese in C ++ zu trainieren. Es gibt einige subtile, aber sehr wichtige Unterschiede, die sie möglicherweise nicht lernen, wenn sie versuchen, sie wie einen seltsamen Java-Dialekt zu behandeln.

Punkt (2) bedeutet, dass es möglicherweise am besten ist, diese alternative Lösung zu verwenden , wenn sich Ihr Team speziell mit Mehrfachvererbung unwohl fühlt (z. B.) und wenn es eine geeignete Lösung gibt, die diese nicht verwendet. Dies hängt jedoch speziell von Ihrem Team ab. Wenn sich Ihr Team dagegen mit dieser alternativen Lösung unwohl fühlt als mit der Mehrfachvererbung, verwenden Sie die Mehrfachvererbung!


Schließlich gibt es Sprachfunktionen von C ++, die man wohl vermeiden sollte. Wenn Sie wissen möchten, was das ist, fragen Sie C ++ - Programmierer , anstatt Programmierer einer anderen Sprache. Einige Beispiele sind Zeigerarithmetik (kein universeller Konsens) und goto.

Ethan Kaminski
quelle
6

Es gibt bereits einige gute Punkte in anderen Antworten, aber ich möchte eine vollständigere Antwort geben und Ihre Fragen und Aussagen einzeln beantworten.


Wenn Java keine Funktion von C ++ bereitstellt, bedeutet dies, dass die Funktion nicht gut ist. Daher sollten wir die Verwendung dieser Funktion verhindern.

Dies wurde ziemlich gut beantwortet: Java ist nicht "der gute Teil" von C ++, und es gibt auch keinen Grund, dies zu glauben.

Insbesondere, obwohl die Vorzüge jedes einzelnen C ++ - Features umstritten sind, sind viele der Features von C ++ 11 / C ++ 14, die nicht Teil von Java sind, nicht unbedingt ausgeschlossen, da die Java-Designer sie für eine schlechte Idee hielten. Als Beispiel hatte Java bis zur Version 8 keine Lambdas, aber sie wurden in C ++ im C ++ 11-Standard eingeführt. Vor Java 8 hätte Ihre Annahme, dass in Java fehlende C ++ - Features aufgrund ihrer "Nicht-Gut" -Funktion nicht vorhanden waren, impliziert, dass Lambdas als Sprachfeature "Nicht-Gut" sind (zum Schrecken der LISPer überall, auch wenn sie nicht gut sind) wahrscheinlich entsetzt genug, um zu hören, dass Sie Java anscheinend tatsächlich mögen ). Aber jetzt haben die Java-Designer Lambdas mit ihrem Gütesiegel versehen, und jetzt sind sie eine gute Sache.

Um auch in Java 8 ein wenig tiefer zu gehen, sind Lambdas-as-Closures nicht so flexibel wie die Lambdas von C ++ 14, aber dies kann eher an den Einschränkungen der JVM-Architektur liegen, als an der bewussten Entscheidung, dass der flexiblere Ansatz von a schlecht ist Perspektive des Sprachdesigns.


C ++ - Code mit C ++ - spezifischen Funktionen (z. B. Friend-Funktionen, Mehrfachvererbung) kann nur von C ++ - Programmierern gepflegt oder überprüft werden. Wenn wir jedoch nur C ++ wie Java schreiben (ohne C ++ - sprachspezifische Funktion), kann der Code von beiden gepflegt oder überprüft werden C ++ und Java Programmierer.

Dies ist die Hauptsache, auf die ich antworten wollte.

Generell kann es sinnvoll sein, Code-Reviews von Programmierern zu erhalten, die mit der von Ihnen verwendeten Sprache nicht vertraut sind. Sie können Ihnen wertvolle Rückmeldungen über die Klarheit Ihrer Funktions- / Methodennamen und Kommentare geben. Wenn die Sprache einer oder mehreren bereits bekannten Sprachen ähnlich ist, kann sie möglicherweise dem grundlegenden Programmablauf folgen und möglicherweise logische Fehler abfangen.

Es ist jedoch nicht der Fall, dass diese Art der Überprüfung jemals "so gut wie" oder "gleichwertig" mit der Überprüfung von Entwicklern ist, die die von Ihnen verwendete Sprache tatsächlich kennen. Dies liegt im Wesentlichen daran, dass das Aussehen einer Sprache in der Regel geringfügige Unterschiede verdeckt, während das Verhalten einer Sprache (insbesondere im Fall von C ++ und Java) für die Sprache möglicherweise nicht idiomatisch und / oder immer noch zu verwirrend ist für die Rezensenten.

Lassen Sie uns zunächst überlegen, was es bedeuten würde, C ++ so zu gestalten, dass es wie Java aussieht. Im einfachen Fall können Sie newObjekte wie in Java instanziieren:

Foo foo = new Foo();

Aber Objekte instanziiert diese Weise Verwendung ->anstelle von .Methoden aufrufen, wenn Sie also Methode wollen ruft wie Java zu suchen, müssen Sie stattdessen schreiben:

Foo& foo = *new Foo();

Aber das ist nicht idiomatisch; Insbesondere muss der Speicher später mit bereinigt werden delete &foo, was einige erfahrene C ++ - Entwickler möglicherweise nicht einmal als gültigen Code erkennen . In beiden Fällen gibt es lustige Nicht-Java-ähnliche Symbole gänzlich besprüht, so dass wir nicht ganz die Sprache Java „aussehen“ machen. (Sie könnten die *newVerwendung von #define New *newoder, schlimmer noch, eliminieren #define new *new, aber dann bitten Sie nur Ihre Mitentwickler, Sie zu hassen.) Und, wie oben erwähnt, deletegibt es in Java auf keinen Fall (wie in einer anderen Antwort erwähnt) ) Sie können die Objektnutzung niemals so aussehen lassen wie in Java, ohne dass Speicherlecks auftreten.

Modernes C ++ enthält jedoch intelligente gemeinsame Zeiger, die sich stark wie die speicherverwalteten Variablenreferenzen von Java verhalten. Überall in Java, wo Sie schreiben könnten Foo foo = new Foo();, könnten Sie stattdessen schreiben:

std::shared_ptr<Foo> foo = std::make_shared<Foo>();

Jetzt verwenden Sie eine Sprachfunktion, die Java unter der Haube sehr ähnelt. Aber plötzlich müssen Sie Nicht-C ++ - Rezensenten eine Menge erklären: Was ist das für ein shared_ptrZeug? Was sind die subtilen kniffligen "Fallstricke" make_shared? (Es wird die perfekte Weiterleitung verwendet, die einige Fehlerfälle aufweist und dazu führen kann, dass der "falsche" Konstruktor aufgerufen wird.) Warum müssen Methoden mit aufgerufen werden ->, aber die Verwendung .mit bestimmten Methoden ist vom Compiler zulässig? ( shared_ptrHat seine eigenen Methoden.) Wenn die Methode Foo::reset(void)existiert, ein unachtsamer Entwickler könnten versuchen , es mit zu nennen foo.reset(), die (wenn es nur einen gemeinsamen Zeiger auf diese Instanz von ist , Foowenn der Anruf auftritt) den zugrunde liegenden Speicher löschen und zunichte machen foo, und Java-Entwickler werden dieses Problem wahrscheinlich nicht bemerken.

Außerdem C ++ hat eine Menge von Gefahren , die spezifisch auf die Sprache. Wie ich am besten beurteilen kann, lernen die meisten C ++ - Entwickler, mit diesen Fallstricken umzugehen, indem sie nach und nach ihre eigene Ausdrucksweise für "sichere" C ++ - Praktiken entwickeln, die für sie oder ihr Entwicklungsteam häufig etwas Besonderes ist (siehe zum Beispiel die vorhandene Antwort, in der das erwähnt wird) Die Codierungspraktiken von Google und der Kommentar dazu lauten: "Erfahrene C ++ - Veteranen lehnen normalerweise die Codierungsrichtlinien von Google ab." Alle Behauptungen, dass die Sprache möglicherweise zu kompliziert ist, scheinen (zumindest nach meiner Erfahrung) in der Regel mit einer Variation von "Nun, hör auf, sie falsch zu verwenden" zu stimmen. Mir ist klar, dass dies eine äußerst negative Sichtweise der C ++ - Community ist, und es gibt sicherlich erfahrene Entwickler, die eher bereit sind, Sprachlernern zu helfen, aber es gibt sie scheint eine gewisse Abwehrbereitschaft gegenüber z. B. undefiniertem Verhalten zu sein (siehe z. B. einen Großteil der Diskussion in meinem Link "Fallstricke" oben).

Java-Entwickler werden einfach nicht hilfreich sein, um diese Fallstricke durch Code-Überprüfung zu finden und zu korrigieren.


Sie werden möglicherweise gebeten, den Code eines Tages nach Java zu konvertieren.

Es ist absolut berechtigt - lobenswert, auch - zu versuchen, zu berücksichtigen, was in Zukunft mit Ihrem Code geschehen könnte, während Sie sich in der Entwurfsphase befinden.

Aber zunächst scheint diese spezielle Überlegung eine entfernte Möglichkeit zu sein: Code wird in der Regel entweder so wie er ist wiederverwendet (zum Beispiel könnten Sie einen Teil oder den gesamten funktionierenden C ++ - Code mithilfe einer JNI-Schnittstelle in eine zukünftige Java-Software einbinden) oder vollständig neu geschrieben als direkt manuell "transkribiert".

Und zweitens sagen Sie später:

Für jede sprachspezifische C ++ - Funktion (z. B. Mehrfachvererbung) sollten Alternativen in Java implementiert werden.

Dies hebt im Wesentlichen Ihren "In Java konvertieren" -Punkt auf. Wenn Software in idiomatischem C ++ geschrieben und dann in idiomatisches Java konvertiert wird, besteht kein Grund zu der Annahme, dass diese Konvertierung durch eine präzise Eins-zu-Eins-Zuordnung von C ++ - Features zu Java-Features erfolgen würde (oder könnte!).


Code ohne C ++ - spezifische Funktionen kann normalerweise besser gewartet werden.

Es ist nicht klar, was Sie hier meinen, aber ich stimme einem Teil davon zu: Wenn Sie nicht sehr vorsichtig sind und selbst wenn Sie vorsichtig sind, können C ++ - Funktionen zu Problemen mit der Wartbarkeit führen. Die C ++ FQA Lite (eine Website, die kritisch gegenüber der Sprache und ihren Anhängern ist und zumindest so aussieht, als würde sie diese Sprache ziemlich gut verstehen) gibt dies an

... 80% der Entwickler verstehen höchstens 20% der Sprache. Es ist nicht dasselbe 20% für verschiedene Leute, also rechnen Sie nicht damit, dass sie den Code des anderen verstehen.

BITTE BEACHTEN SIE: Wenn Sie ein C ++ - Fan sind und in meiner Antwort auf diesen Punkt eingehen, sind Sie geneigt, zu den Kommentaren zu springen, um zu argumentieren, dass der Autor der FQA C ++ nicht wirklich versteht oder in den meisten seiner Argumente unaufrichtig ist Beachten Sie, dass (1) genau zwei Sätze, nachdem ich ihn zitiere, ich anerkenne, dass die FQA eine sehr voreingenommene Quelle ist, und (2) es ist nicht wirklich wichtig, was ich versuche zu sagen, ob der FQA-Autor C ++ versteht oder nicht , und ich versuche nicht, C ++ zu schlagen, und Sie sollten den Rest des Beitrags lesen, ohne davon auszugehen, dass ich Anti-C ++ bin, nur weil ich die FQA zitiert habe. Ende der Notiz.

In ähnlicher Weise hasst Linus Torvalds C ++ im Wesentlichen aus diesem Grund (Warnung: Link beinhaltet viel Fluchen im wahrhaft berüchtigten Linus-Stil).

Offensichtlich sind diese Einstellungen sehr voreingenommen, aber selbst C ++ - Befürworter sagen oft, dass Sie nicht den gesamten Sprachfeaturesatz verwenden sollten (siehe auch die Codierungsrichtlinien von Google; außerdem Bjarne Stroustrup, der Schöpfer von C ++ , hat öffentlich erklärt, "In C ++ gibt es eine viel kleinere und sauberere Sprache, die Schwierigkeiten hat, herauszukommen").

Ich denke, die Idee, dass C ++ - Funktionen möglicherweise zu einfach zu missbrauchen sind, hat einen gewissen Wert, insbesondere wenn Sie aus einem Java-Hintergrund stammen. Darüber hinaus hat die Idee, diese Probleme durch Beschränkung auf eine Teilmenge der Sprache zu lindern, ihre Berechtigung.

Die Entscheidung, welche Teilmenge basierend auf einer anderen Sprache verwendet werden soll , scheint jedoch nicht der richtige Ansatz zu sein, es sei denn, die "andere Sprache" ist C, da es tatsächlich eine C-ähnliche Teilmenge der C ++ - Sprache gibt. (Linus bezieht sich in seiner obigen Randalierung darauf, und Scott Meyers bezeichnet diese Teilmenge sogar als "Teilsprache".) Javas Laufzeitparadigma (mit Speicherbereinigung, ausgeführt auf einer VM) unterscheidet sich grundlegend von C ++ Es ist nicht klar, ob es nützliche Lektionen zur Verwendung von C ++ gibt, und wie oben erwähnt, kann der Versuch, Lektionen über C ++ direkt aus Java zu ziehen, zu einem sehr nicht-idiomatischen Code führen.

Versuchen Sie stattdessen, Ihre "akzeptable Teilmenge" der Sprache zu definieren, um zu verstehen, wie die Sprache idiomatisch verwendet werden kann. Wenn Sie eine ziemlich restriktive Teilmenge wünschen, die noch viele der Funktionen von C ++ nutzt, die über das hinausgehen, was C bietet, ist die oben erwähnte Google Coding-Richtlinie möglicherweise ein guter Ausgangspunkt. Klar, es gibt Entwickler, die sagen, dass es für einige der Einschränkungen von Google kein "rationales Argument" gibt , aber es sei denn, Sie möchten Alexandrescu von seiner Arbeit an der D-Sprache fernhalten (was Ihnen selbst etwas sagen sollte) wahrscheinlich okay Es ist sicherlich besser, als C ++ in Java zu verwandeln.

Ein weiterer guter Ausgangspunkt für eine Reihe von Code-Richtlinien sind die neuen C ++ Core-Richtlinien , die von Bjarne Stroustrup und Herb Sutter in Arbeit sind.

Die einzige andere Möglichkeit, mit den Mängeln von C ++ umzugehen, besteht darin, eine andere Sprache auszuwählen. Es hört sich so an, als ob Sie Java mögen, und Sie glauben, dass dieses Projekt möglicherweise irgendwann in Java konvertiert wird. Wie in einer anderen Antwort erwähnt, können Sie einfach ... mit Java beginnen.

Es gibt zwei Gründe , warum Sie wirklich wirklich vielleicht brauchen etwas anderes als Java zu verwenden:

  1. Sie brauchen wirklich die Laufzeitleistung. In diesem Fall hilft es Ihnen wahrscheinlich nicht, C ++ wie Java zu behandeln, da Java-ähnliche Techniken wie Shared Pointers Ihre Laufzeitleistung beeinträchtigen.
  2. Sie benötigen die Software, um auf einer unbekannten Plattform zu arbeiten, die die JVM noch nicht unterstützt. In diesem Fall stecken Sie wahrscheinlich in Sprachen mit GCC- oder Clang-Frontends fest. C und C ++ sind offensichtliche Kandidaten, aber Sie könnten auch etwas wie Rust untersuchen. (Quick Plug: Ich habe Rust nicht in großem Umfang verwendet, aber es sieht großartig aus und ich bin gespannt darauf, so bald wie möglich an einem größeren Rust-Projekt zu arbeiten. Ich denke, jeder, der ein C ++ - Projekt in Betracht zieht, sollte Rust als Alternative in Betracht ziehen.)

Für jede sprachspezifische C ++ - Funktion (z. B. Mehrfachvererbung) sollten Alternativen in Java implementiert werden. Wenn dies nicht der Fall ist, ist das Entwurfsmuster oder die Codearchitektur problematisch.

Ich habe das schon etwas angesprochen, aber ich habe deinen zweiten Satz absichtlich weggelassen.

Ich bin nicht davon überzeugt, dass so etwas constexpr, was in einer teilweise JIT-fähigen Sprache wie Java keinen Sinn ergibt, ein Hinweis auf eine ungültige Architektur ist. Ich bin offen für die Idee , dass die übermäßige Verwendung von Template - Meta-Programmierung könnte mehr Probleme als es wert ist, vor allem jetzt , dass constexprdafür Funktion Auswertung kompilierte Zeit existiert, aber es ist klar , aus dem Fall , constexprdass es keine Design - Fehler , wenn Sie Verwenden Sie es: Sie stellen lediglich sicher, dass einige Berechnungen ausgeführt werden, bevor Sie den Code ausführen. Dies ist eine enorme Leistungssteigerung (siehe zum Beispiel diesen Eintrag für das n-body-Problem von The Benchmark Game , das alle anderen Einträge außer einem anderen übertrifft) geschrieben in C ++,

Kyle Strand
quelle
5
Der FQA-Autor fällt definitiv in die Gruppe "höchstens 20% der Sprache verstehen". Hier gibt es ein paar Antworten, die sachlich falsch sind, und eine ganze Reihe weiterer, die einfach den Sinn verfehlen, illustriert mit Strohmann nach Strohmann.
Ben Voigt
2
Viele (fast alle?) Der Beschwerden in der C ++ FQA sind Unsinn. Moderne Sprachen sind riesig. C ++ ist im Vergleich zu Python, Ruby, Perl und Java eher klein. Stellen Sie in diesen Sprachen eine grundlegende Frage zum Stackoverflow, und die erste Antwort lautet fast unweigerlich "Warum haben Sie das nicht getan import SomeVeryBasicPackageund tun dies einfach ?". Stellen Sie eine erweiterte Frage und die erste Antwort ist fast zwangsläufig entlang der Linien von „Warum haben Sie nicht import SomeMagicalPackageund nur tun , dass ?“
David Hammen
1
@DavidHammen Ich denke, die Aufteilung von 80/20 bezieht sich auf Kernsprachfunktionen, nicht nur auf Standardbibliothekskomponenten. In diesem Fall scheinen die von Ihnen genannten Sprachen, mit der möglichen Ausnahme von Perl, nicht so umfangreich und kompliziert zu sein wie C ++. Auf jeden Fall war das ein sehr kleiner Teil meiner Antwort, und ich gab zu, dass es eine voreingenommene Quelle ist.
Kyle Strand
1
VM / verwaltete Sprachen sind offensichtlich unter der Oberfläche viel komplizierter, aber ich meine, aus Sicht der Nutzung kompliziert.
Kyle Strand
1
Ich habe keine Ahnung, ob Ihre Theorie korrekt ist, obwohl ich in meinem Fall definitiv C ++ und C getrennt gelernt habe und meine C ++ - Klasse wirklich ziemlich gründlich war. Aber das volle Zitat über das 20/80 Split ist , dass jeder Programmierer ein kennt verschiedenes 20% der Sprache, die nicht durch die meisten Programmierer erklärt wird , dass der C - Teil der Sprache unabhängig gelehrt. Wie auch immer, wenn Sie detailliert erläutern möchten, wie C ++ eine robustere Programmierung ermöglicht (ich behaupte, ich habe es schon einmal gesehen, verstehe es aber nicht), sollten Sie dies lieber in einem Chatroom oder so tun, als in den Kommentaren hier .
Kyle Strand
5

Angenommen, ich kann C ++ nur in der Umgebung des Projekts verwenden. Ist es sinnvoll, die Verwendung einiger Sprachfunktionen zu verhindern, die in C ++ enthalten sind, in Java jedoch nicht (z. B. Mehrfachvererbung, Überschreiben von Operatoren)?

Nein.

Wenn Sie "aufgrund der Umgebung des Projekts" nur C ++ verwenden, gibt es, wenn überhaupt, kaum einen Grund, überhaupt über eine andere Technologie nachzudenken , ganz gleich, wie sehr Sie sie persönlich bevorzugen / hoffen, sie zu verwenden / zu evangelisieren.
Ob "Technologie X" oder "Y" ein bestimmtes Feature unterstützt, sollte sich nicht auf die Art und Weise auswirken , in der Sie Ihre C ++ - Anwendung erstellen.
Es ist eine C ++ - Anwendung, vermutlich aus irgendeinem "guten Grund" (jetzt oder in der Vergangenheit), also sollten Sie sie als C ++ - Anwendung schreiben , wobei Sie das verwenden, was auch immer diese spezielle "Toolbox" bietet.

Wenn die Anwendung auf eine andere Technologie portiert werden muss (und nur dann), sollten Sie Funktionen auf anderen Plattformen in Betracht ziehen. Es gibt keinen Punkt „cutting off Nase trotz deines Gesichts“ auf der off-Chance , dass etwas könnte passieren. Denken Sie jedoch daran, dass das Umschreiben im Großhandel eine teure und riskante Angelegenheit ist, die das Management wahrscheinlich nicht ohne einen guten Grund übernehmen wird.

Vor einigen Jahren gab es eine ähnliche Debatte ("zu verwenden oder nicht zu verwenden") in der Visual Basic [.Net] -Welt, in der jemand die gute Idee hatte, dass Sie Visual Basic-Anwendungen schreiben sollten, ohne eine der [Kernsprachen] zu verwenden. Funktionalität, die vom Microsoft.VisualBasic-Namespace bereitgestellt wird. Es wäre, als würde man versuchen, eine C ++ - Anwendung ohne den Namespace std :: zu schreiben. OK, es ist möglich, aber warum sollte sich irgendjemand, der bei klarem Verstand ist, die Mühe machen, dies zu tun?

Phill W.
quelle
1
Zu Ihrem letzten Punkt zu Visual Basic: Das Problem bei solchen Herstellerbibliotheken ist, dass sie proprietär sind. Wenn Sie sie verwenden, müssen Sie sich an diesen Anbieter binden. Der Anbieter wird es mögen, wenn Sie angekettet werden, aber auf lange Sicht nicht: Sie können die Software eines anderen Anbieters nicht verwenden, ohne alles neu zu schreiben, was auf herstellerspezifischen Funktionen beruht. Je häufiger Sie herstellerspezifische Funktionen verwenden, desto höher sind die Kosten für den Anbieterwechsel, sodass Ihr Anbieter Änderungen erzwingen kann. Dies ist einer der Gründe, warum freie (wie in Freiheit!) Software so wichtig ist.
cmaster
Das Microsoft.VisualBasicNamespace-Ding ist ein bisschen langweilig. Es ist viele Jahre her, dass ich es das letzte Mal benutzt habe, aber zumindest zu Beginn war es hauptsächlich darauf ausgerichtet, die Abwärtskompatibilität mit VB6 zu gewährleisten (und / oder VB6-Programmierern das Gefühl zu geben, "zu Hause" zu sein). Es stellte hauptsächlich Funktionen bereit, die bereits im Rest des Frameworks in einer moderneren (und besser integrierten) Form verfügbar waren, sodass es in neuen Projekten selten Sinn machte, sie zu verwenden. Im Gegensatz dazu befindet sich im std::Namespace die gesamte Standardbibliothek. Wenn Sie dies vermeiden, wird die gesamte BCL in .NET vermieden.
Matteo Italia
2

Die aktuellen Antworten sagen alle, dass dies eine schlechte Sache ist, da Sie die von Ihnen verwendete Sprache ausnutzen und auch erklären sollten, warum eine C ++ - Funktion nicht "schlecht" ist, nur weil sie nicht in Java enthalten ist. Ich werde dies aus einem anderen Blickwinkel beantworten.

Es ist eine Sache, komplexe C ++ - Funktionen wie Mehrfachvererbung, Überladen von Operatoren und das Definieren einer eigenen Vorlage zu vermeiden.

Aber jedes Problem, das mehr als die einfachste Aufgabe erledigt:

  • reserviert Speicher,
  • verbindet dieses Geld mit Punkten
  • Bauen Sie also Datenstrukturen auf
  • Ermöglicht dann die Wiederverwendung des Speichers, wenn dies ohne Gefahr möglich ist

Es gibt keine gemeinsame Untermenge von Java und C ++, die das oben Genannte ermöglicht. Daher ist es unmöglich, das zu tun, wonach Sie fragen. (Wenn Sie nach Java und C # fragen, haben Sie eine viel bessere Chance, da beide Garbage Collectors verwenden.)

Sie könnten jedoch verlangen, dass der Code so geschrieben wird, dass ein Java-Entwickler verstehen kann, was zu tun ist (aber nicht das detaillierte "Wie"), und dies wäre sinnvoll.

Sie können auch Ihre eigene Sprache entwerfen, die Sie sowohl in C ++ als auch in JAVA implementiert haben.

Ian
quelle
0

Niemand sollte Code schreiben, den andere Programmierer nicht verstehen. Wenn Sie der Meinung sind, dass die Sprachsperre ein Problem darstellt, warten Sie, bis Sie die Entwicklersperre aktiviert haben. Einer hält dich eher als Geisel als der andere.

Es gibt wirklich keine technischen Gründe. Was Sie erstellt haben, ist ein Szenario, in dem eine Sprache aus irgendeinem Grund verwendet wurde, aber viele aktuelle und möglicherweise zukünftige Entwickler es nicht wirklich verstehen.

Ich vermute, Java-Entwickler schreiben C ++ wahrscheinlich so, wie sie es in Java schreiben. Warum also eine Regel? Möglicherweise entdecken Sie einige C ++ - spezifische Funktionen, die mit ein wenig C ++ - Anleitung / Dokumentation für Ihre Java-Entwickler einfacher zu implementieren und zu warten sind, als die große Menge an Java-Chaos, mit dem sie sonst zu kämpfen hätten.

Dies war ein Argument für die Probleme von BASIC-Programmierern, die auf objektorientierte Sprachen umsteigen. Es ist nicht so, dass sie OOP-Praktiken zum Nachteil neuer Entwickler implementieren, die sie nicht verstehen, sondern dass sie sie überhaupt nicht implementieren. Wenn sie das tun, verstehen sie es normalerweise falsch. Wenn etwas schlecht gemacht wird, muss es unabhängig vom Grund entfernt werden.

Abgesehen davon, dass jemand Code blind kopiert und einfügt, wird er dies in vielen Bereichen tun, die er sowieso nicht versteht.

JeffO
quelle