Ich bin ein Programmierer in C und C ++, obwohl ich mich nicht an beide Sprachen halte und eine Mischung aus beiden schreibe. Manchmal ist es natürlich besser, Code in Klassen zu haben, möglicherweise mit Überladung des Operators oder Vorlagen und der ach so tollen STL. Manchmal ist die Verwendung eines einfachen C-Funktionszeigers viel besser lesbar und klarer. So finde ich Schönheit und Praktikabilität in beiden Sprachen. Ich möchte nicht in die Diskussion "Wenn Sie sie mischen und mit einem C ++ - Compiler kompilieren, ist es keine Mischung mehr, es ist alles C ++" einsteigen. Ich denke, wir alle verstehen, was ich unter Mischen verstehe. Außerdem möchte ich nicht über C vs C ++ sprechen, diese Frage dreht sich alles um C ++ 11.
C ++ 11 führt, wie ich finde, wesentliche Änderungen an der Funktionsweise von C ++ ein. Es wurden jedoch zahlreiche Sonderfälle, Ausnahmen und Unregelmäßigkeiten eingeführt, die das Verhalten verschiedener Features unter verschiedenen Umständen ändern und die Mehrfachvererbung sowie Bezeichner, die als Schlüsselwörter fungieren, und Erweiterungen einschränken von String-Literalen, Lambda-Funktionsvariablenerfassung usw.
Ich weiß, dass irgendwann in der Zukunft, wenn Sie C ++ sagen, jeder C ++ 11 annehmen würde. Ähnlich wie wenn Sie heutzutage C sagen, meinen Sie höchstwahrscheinlich C99. Das bringt mich dazu, C ++ 11 zu lernen. Wenn ich weiterhin Code in C ++ schreiben möchte, muss ich diese Funktionen möglicherweise irgendwann verwenden, nur weil meine Kollegen dies getan haben.
Nehmen Sie zum Beispiel C. Nach so vielen Jahren lernen und schreiben immer noch viele Menschen Code in C. Warum? Weil die Sprache gut ist. Was gut bedeutet, ist, dass viele der Regeln befolgt werden, um eine gute Programmiersprache zu erstellen. C ist also nicht nur mächtig (was leicht oder schwer ist, fast alle Programmiersprachen sind es), sondern es ist auch regelmäßig und hat, wenn überhaupt, nur wenige Ausnahmen. C ++ 11 glaube ich jedoch nicht. Ich bin nicht sicher, ob die in C ++ 11 eingeführten Änderungen die Sprache verbessern.
Die Frage ist also: Warum sollte ich C ++ 11 lernen?
Antworten:
Sie sollten es lernen, wenn Sie denken, dass Sie es in Zukunft wissen müssen, um einen Job zu bekommen. Wenn Sie zuversichtlich sind, dass Sie als C / C ++ [und was auch immer Sie sonst noch wissen] in der Belegschaft marktfähig bleiben, lernen Sie es nicht. Wenn Ihr Chef Sie auffordert, C ++ 11 zu verwenden, sagen Sie "Nein, das mache ich nicht". Wenn er dich feuert, geh woanders arbeiten. Lernen Sie C ++ 11, wenn Sie davon ausgehen, dass Sie bald keine zufriedenstellende Beschäftigung mit den Fähigkeiten finden werden, die Sie derzeit kennen.
Wollte meine Begründung klarstellen: Ich bin nicht Anti-C ++ 11. Wenn Sie nur sagen, Sie könnten die Frage des OP auf "Warum sollte ich X lernen" verallgemeinern. Ich habe nie ML, Schema oder Haskell gelernt, weil ich einen Job bei C und C ++ habe. Ich bin mir sicher, dass diese Sprachen für jemanden nützlich sind, aber sie sind für mich nicht von Vorteil, wenn ich sie gerade lerne. Wenn mir jemand gutes Geld zum Programmieren in ML anbietet, könnte ich versuchen, es zu lernen.
quelle
Es ist einfach. Mit C ++ 11 wird Code erheblich einfacher, übersichtlicher und schneller zu schreiben.
nullptr
ist eine große Verbesserung gegenüber dem alten0
. Es ist typsicher und konvertiert nicht, wenn es nicht anders sein sollte0
. Es ist eine gute Sache,nullptr
die nicht in eine konvertieren wirdint
. Es macht keinen Sinn, dass das überhaupt passiert. Wissen Sie, was das C ++ - Komitee bei seinen Überlegungen herausgefunden hat#define NULL nullptr
? Sachen wiechar c = NULL;
. Wie schrecklich ist das? Der einzige Grund, warum es hier eine Ausnahme gibt, ist, dassbool
es sich um einen ganzzahligen Typ handelt, was völlig falsch ist - aber das gab es schon in C ++ und in C. Die Tatsache, dassnullptr
keine Konvertierung durchgeführt wird, ist gut , es ist großartig und Sie sollten es lieben.Oder wie wäre es mit rWertreferenzen und variadischen Vorlagen? Schnellerer, allgemeinerer Code. Das ist ein totaler Gewinn genau dort.
Wie wäre es mit den Bibliotheksverbesserungen? Sachen wie
function
,unique_ptr
undshared_ptr
sind so viel besser als das, was es vorher war, ist es unmöglich , zu argumentieren , dass die C ++ 03 viel besser war.Nicht einmal entfernt gleichwertig. Makros sind aus sechs Milliarden Gründen schlecht. Ich werde sie hier nicht alle zitieren, aber es ist bekannt, dass Makros für so ziemlich alle Zwecke vermieden werden sollten, für die sie möglicherweise vermieden werden können. Was wirst du tun, wenn es ist?
Oh warte, ich hoffe du hast nicht zugenommen oder so
x
. Wofür die Template-Funktionsversion absolut immun ist. Ich hoffe auch, dass Sie zum Beispiel Namespaces nicht mögen .In einer funktionalen API, z. B. STL-Algorithmen, ist die Referenz in Ordnung. Wenn es sich um einen gespeicherten Rückruf handelt, müssen Sie nach Wert erfassen. Unabhängig davon, welche Dokumentation Sie zu der Funktion haben, sollte klar angegeben werden, welche erforderlich ist. Die Tatsache, dass der Code in einem Lambda geschrieben ist, spielt keine Rolle für das Problem, auf lokale Variablen zu verweisen. Wenn Sie ein reguläres Funktionsobjekt übergeben, haben Sie genau die gleichen Probleme. Und es ist kein Problem. Überhaupt. Weil es von Natur aus offensichtlich ist, wann Sie auf lokale Variablen verweisen können und wann nicht.
Es gibt viele Menschen, die sich morgens nicht die Zähne putzen. Es gibt viele Mörder, Vergewaltiger und Prostituierte. Und Politiker. Menschen, die Selbstmord begehen. Würden Sie argumentieren, dass dies diese Aktivitäten gut oder nützlich macht? Natürlich nicht. Es ist ein logischer Irrtum, dass es gut oder nützlich sein muss, nur weil es jemand getan hat.
C wird noch aus drei Gründen geschrieben: weil C ++ eine zu implementierende Hündin ist, zum Beispiel im eingebetteten Modus oder im Kernel-Modus; weil ältere Codebasen in C geschrieben sind und das Upgrade zu viel kosten würde, obwohl dies angesichts der hervorragenden C-Interop von C ++ auch fraglich ist; und weil die Leute, die es schreiben, nicht wissen, wie man programmiert. Das ist es. Es gibt keinen anderen Grund, C zu schreiben.
Wie wäre es mit den pathetischen Arrays im C-Stil, für ein einfaches Beispiel? Die Anzahl der Menschen, die Arrays und Zeiger nicht direkt in den Kopf bekommen können, ist obszön. Ganz zu schweigen von der Tatsache, dass die C-Standard-Bibliothek unglaublich unsicher ist.
Ihre Kernargumente sind voller logischer Irrtümer und Missverständnisse.
quelle
C ++ 11 ist keine neue Sprache. Es ist nur eine Erweiterung / Modifikation von C ++, die Sie bereits kennen. C ++ 11 besteht wie jede andere Programmiersprache aus Funktionen. Viele von ihnen waren von früher da, einige von ihnen sind neu. Aber Ihre Frage ist wirklich, sollte ich alle Funktionen der Sprache lernen (in diesem Fall C ++ 11) oder mich nur mit 90% davon vertraut machen?
IMO, auch wenn Sie nicht alle Sprachen verwenden, sollten Sie zumindest nachlesen, was die neuen Funktionen für Sie tun. Viele von ihnen wurden eingeführt, um das Schreiben von Bibliotheks- / Framework-Code (insbesondere von Vorlagen) zu vereinfachen (z. B. bevor eine perfekte Weiterleitung in C ++ 11 nicht möglich war). Wenn Sie diese Funktion jedoch noch nie benötigt haben, haben Sie die Chance gewonnen bemerken nicht, dass diese Funktionen in C ++ 11 hinzugefügt wurden.
Auf der anderen Seite, wenn Sie zuvor Bibliotheks- / Kerncode geschrieben haben, der einige STL / Boost-Funktionen imitiert, und sich durch die Sprache eingeschränkt fühlen, weil Sie dann zu 95% eine sehr coole, elegante Lösung gefunden haben Sie wurden gestoppt, weil Sie herausgefunden haben, dass die Sprache einfach nicht das unterstützt, was Sie wollen. Sie werden die wirklich großartige Leistung von C ++ 11 erkennen. Seitdem unser Team ein Upgrade auf VS2010 durchgeführt hat (und wir dabei Boost entdeckt haben), konnte ich verrückten, großartigen Code entwickeln, der vor Dingen wie Verweisen auf R-Werte und Weiterleitung von Vorlagenparametern einfach unmöglich wäre.
Auch Dinge wie Lambda mögen fremd aussehen, aber sie führen kein neues Konstrukt ein. Stattdessen machen sie das, was wir früher hatten, so viel einfacher zu schreiben. Zuvor musste jede Lambda-Funktion eine eigene Klasse sein. Jetzt ist es nur {... code ...}. Liebe es.
Der Schlüssel ist, sich diese Funktionen nicht anzuschauen und zu überlegen, wie entmutigend die Liste ist. Verwenden Sie stattdessen C ++ wie gewohnt, und wenn Sie auf ein Szenario stoßen, in dem diese neuen C ++ 11-Funktionen nützlich sind (mehr als 90% der Benutzer werden diesen Punkt nie erreichen), werden Sie sehr glücklich sein, dass die Erweiterung funktioniert auf die sprache wurde eingegangen. Im Moment würde ich vorschlagen, dass Sie nur genug über die Sprache lernen, um zu wissen, was es gibt, und nicht unbedingt, wie Sie alles verwenden.
quelle
Wenn Sie dies tun, scrollen Sie nach oben oder öffnen eine neue Quelldatei und fügen dort die Definition der Funktion hinzu. Dann müssen Sie zurückgehen und weiterarbeiten, was Sie bis zu einem gewissen Grad ablenkt.
Wenn andere Leute Ihren Code lesen, ist ein Lambda in manchen Fällen möglicherweise selbstdokumentierender, anstatt zu sagen: "Oh, was macht diese Funktion?" und wenn Sie zu seiner Deklaration springen, können Sie sich einfach ansehen, was er an seiner eigenen Stelle tut.
Es gibt ein nettes Gespräch von Herb Sutter über Lambdas, vielleicht kann er dich besser überzeugen:
http://channel9.msdn.com/events/PDC/PDC10/FT13
Weil Sie dies nicht tun können, wenn Sie STL-Algorithmen oder eine Funktion verwenden, für die Sie eine Funktion übergeben müssen.
Es gibt keine Möglichkeit, diese Verwendung anstelle von Lambdas zu rechtfertigen. Sie können Ihren Code nicht überall mit Makros füllen. Makros und Funktionen haben unterschiedliche Zwecke, und eines ist im Allgemeinen kein Ersatz für das andere.
Ich stimme zu, das ist hässlich. Ich erinnere mich jedoch, dass ich sagte: "Warum zum Teufel sollte ich die Art dieses Ausdrucks herausfinden, obwohl der Compiler darauf schließen kann?" in vielen Fällen. Dies kann in diesen Momenten sehr hilfreich sein.
Um zusammenzufassen:
Obwohl die neuen Funktionen von C ++ 11 in ihrer Syntax hässlich erscheinen, glaube ich, dass man sich in kurzer Zeit an sie gewöhnen kann. Jedes neue Sprachkonstrukt ist zunächst schwer zu lernen; Stellen Sie sich das erste Mal vor, als Sie gelernt haben, eine ganze Klasse zu schreiben: Setzen Sie die Deklaration in die Header-Datei, nicht vergessen Sie das zusätzliche Semikolon am Ende, setzen Sie die Definitionen in die Quelldatei, einschließlich der Header-Datei, und stellen Sie dabei sicher, dass es einen Schutz zum Verhindern gibt mehrfache Einschlüsse, nicht zu vergessen der Gültigkeitsbereichs-Auflösungsoperator in den Member-Funktionsdeklarationen und so weiter ...
Aber ich bin mir ziemlich sicher, dass Sie sich nach dem Schreiben einiger Klassen daran gewöhnen und nicht über die Komplexität dieses Prozesses nachdenken: Weil Sie wissen, dass eine Klasse Ihre Arbeit als Programmierer viel einfacher macht und Sie das Hilfsprogramm Die Einnahmen aus diesem neuen Konstrukt sind viel größer als der Nutzwertverlust während des Versuchs, die Sprache zu lernen . Ich denke, dies kann der Grund sein, warum man versuchen sollte, C ++ 11 zu lernen oder auf ähnliche Weise zu verwenden.
quelle
bool is_alive;
undbool thisSpecialObjectOfMineIsAlive;
. Beide machen dasselbe, aber der zweite sieht wirklich hässlich aus. Warum? Weil ich fälschlicherweise dachte, dass das Setzen von mehr Informationen es klarer macht, aber es hat das Gegenteil bewirkt. Stroustrup meinte es gut, indem er uns Features gab, aber er machte es einfach nicht gut aussehend. Für mich zeigt dies ein schlechtes Design.Tatsächlich hat das OP einige Punkte, was die meisten Antworten betrifft. Aber sie haben eine "ferne" Sicht. C ++ (einschließlich C-Teilmenge) hat eine lange Geschichte, in der im Laufe der Zeit eine Reihe von Funktionen hinzugefügt wurden, von denen einige mehr oder weniger häufig verwendet und - durch ihre Verwendung und Fehler - in andere und andere perfektioniert wurden.
Manchmal kommt es vor, dass nach der Einführung eines neuen Features ein altes Feature nicht mehr benötigt wird oder im Widerspruch dazu steht. Eine "saubere" Sprache sollte so wie sie ist selbstkonsistent sein und nicht mehr benötigte Funktionen sollten entfernt werden.
Aber das Hinzufügen zerstört nichts. Durch Entfernen (oder Ändern) wird vorhandener Code beschädigt, der sich noch in der Produktion befindet. Unabhängig davon, welche Funktion Sie hinzufügen, müssen Sie darauf achten, vorhandenen Code nicht zu beschädigen (insbesondere nicht unbemerkt zu beschädigen , damit er andere Aufgaben ausführt als beabsichtigt ).
Musst du das alles lernen? Ja, weil alle Funktionen früher oder später - im Guten oder im Schlechten - genutzt werden. Ob dies eine gute Sache für die "Qualität" der Sprache ist (zugeben, dass es ein objektives Maß dafür gibt), ist eine andere Geschichte: Wie lange sollte die Abwärtskompatibilität erhalten bleiben? Es ist schwer eine Antwort zu finden, wenn jemand 3 Jahre sagt und einige andere sagen 50.
Die Alternative, um C ++ "normaler" zu halten, ist ... häufiger zu brechen, mit einem Neustart von Grund auf. Es wird aber kein C ++ mehr geben.
Es gibt auch Versuche, dies zu tun (denken Sie zum Beispiel an D: viel orthogonaler als C ++ (sogar 11) tatsächlich ist), aber wie beliebt sind sie? Einer der Gründe für die Schwierigkeit, Schwung zu bekommen, ist die Inkompatibilität mit vielen vorhandenen Codes, die noch ausgeführt werden müssen.
C ++ 11 ist für mich eindeutig ein Kompromiss zwischen neuen Anforderungen und Abwärtskompatibilität. Dies führte zu einer gewissen "Verwirrung" der Spezifikationen und der Implementierung. Bis die Kosten für dieses "Chaos" geringer sind als die Kosten für Inkompatibilität ... müssen Sie diesen Kompromiss einhalten.
Wenn Sie es nicht mehr ertragen können, ... ziehen Sie besser eine andere jüngere Sprache in Betracht. C ++ kann in diesem Sinne einfach nicht vereinfacht werden. Nicht in diesem Alter.
quelle
Auch wenn Sie sich dazu entschließen, die neuen C ++ 11-Funktionen zu ignorieren, profitieren Sie dennoch davon, da sie von der C ++ Standard Library verwendet werden. In C ++ 98 beispielsweise war das Vorhandensein einer Variablen des Typs
vector<string>
aufgrund der Anzahl der Kopien, die erstellt werden mussten, wenn der Vektor größer wurde, potenziell eine Leistungsstörung. Mit dem Move-Konstruktor von C ++ 11 ist dies kein Problem. Tatsächlich wünschte ich mir, C ++ 11 hätte uns mehr neue Funktionen gebracht, nicht weniger - insbesondere in der Standardbibliothek.quelle
Erstens lernen die meisten Schüler heutzutage Java oder .NET, nicht C. Zweitens verwenden die Leute C immer noch, nicht nur wegen seiner Vorteile als Sprache, sondern hauptsächlich, weil es eine riesige Menge vorhandener Software gibt, die in C geschrieben ist und dies erfordert gepflegt und erweitert werden, und da in vielen Fällen (zB Embedded-Plattformen) ein C-Compiler alles ist, was es gibt. Übrigens sind dies einige der Gründe, warum immer noch COBOL geschrieben wird.
Es ist sehr selten, dass ein Programmierer in der Branche anfängt, an einem brandneuen Projekt zu arbeiten, das nicht an eine vorhandene Codebasis gebunden ist, und weiterhin alleine arbeitet. Der Grund für das Erlernen von C ++ 11 ist, dass Sie wahrscheinlich mit Code umgehen müssen, der von anderen Personen geschrieben wurde und die neuen Funktionen verwendet. Außerdem wurden die hinzugefügten Funktionen aus einem bestimmten Grund hinzugefügt. Sobald Sie sie gelernt und benutzt haben, werden Sie sie vielleicht zu schätzen wissen.
quelle
good
bedeutet dies, dass Regeln für eine gute Gestaltung der Programmiersprache befolgt werden. Ich weiß nicht, wo Sie studieren, aber ich kenne 4 oder 5 Länder, und alle beginnen mit C Programmieren zu lernen. Wie ich bereits sagte, gibt es bei C fast keine Ausnahmen (etwas, das in Java anders ist, kann man kaum machen) finde ein Konstrukt, das keine Ausnahme hat).Sie werden zu einem Zeitpunkt in Ihrer C ++ - Karriere kommen, an dem Sie sich sagen: "Ich wünschte, Funktoren wären einfacher" oder "Warum ist NULL ein Int?" und dann werden Sie C ++ 11 verstehen.
quelle
NULL
sollte ein seinint
. Das sollte es nicht. Was ich nicht für richtig halte, ist, ein Konstrukt in der Sprache einzuführen, das dieses Problem löst, aber Ausnahmen einführt. Sie hätten dasselbe besser können sollen.Lernen ist immer von Vorteil. Wissen ist Macht.
Das ist im Grunde die Antwort. Alles andere sind nur Details darüber, wie genau Sie davon profitieren können und welche Fähigkeiten Sie haben, wenn Sie es wissen, und sie sind so zahlreich, dass jede Aufzählung unvollständig wäre.
Ein Beispiel ist Ihre eigene Frage. Man würde es nicht einmal fragen können, ohne zumindest ein bisschen davon zu lernen.
Und wie ich bereits bemerkte, geht es nicht darum, warum man lernt, sondern warum man es einsetzt . Und das ist eine ganz andere Frage.
quelle
Sie sollten C ++ 11 lernen, da Sie mit den hinzugefügten Funktionen besseren Code schreiben können. Einige Leute haben die Typensicherheit von NULL-Zeigern und Lambdas erwähnt, die sehr nett sind. Ich möchte jedoch darauf aufmerksam machen, was meiner Meinung nach die dramatischste Änderung in C ++ 11 ist, insbesondere in einer großen Produktionsumgebung: die Verschiebungssemantik.
C ++ 11 unterstützt die Begriffe "Verschieben" und "Kopieren". In regulärem C ++ haben wir nur den Operator =, der im Grunde beides macht. In Wirklichkeit bringen wir mit einem Bediener zwei unterschiedliche Ideen zum Ausdruck, was gefährlich ist.
Das offensichtlichste Beispiel dafür, wo dies nützlich ist, ist das neue unique_ptr. Es hat die besten Eigenschaften des alten auto_ptr und scoped_ptr. Angenommen, wir möchten einen Zeiger haben, der garantiert der einzige Zeiger ist, der auf ein Objekt zeigt. Wie gehen wir mit a = b um? Nun, bevor wir feststeckten, konnten Sie es entweder komplett verbieten (als scoped_ptr), oder wir konnten tun, was auto_ptr tut, wenn a = b b das Eigentum stiehlt. Dieses Verhalten von auto_ptr ist sehr verwirrend, da a = b tatsächlich b ändert. unique_ptr behandelt dies: a = b ist nicht erlaubt, aber Sie haben a = std :: move (b), um den Besitz zu stehlen. Wie ist das nützlich? Dabei gibt es eine separate (überladene) Version von Swap, die die Verschiebungssemantik anstelle der Kopiersemantik verwendet. Dies bedeutet, dass unique_ptr problemlos ausgetauscht werden kann. Dies bedeutet, dass unique_ptr im Gegensatz zu auto_ptr ist sicher in einem Container zu verwenden und dann sortieren zu sagen. unique_ptr ist im Grunde genommen das A und O der sicheren Speicherverwaltung, wenn Sie nicht mehrere Zeiger auf dasselbe Objekt benötigen.
Ein weiteres gutes Beispiel: Angenommen, Sie haben ein Objekt, das nicht kopiert werden kann. Dies ist in einer Reihe von Situationen nützlich. Sie können dieses Objekt niemals von einer Funktion zurückgeben, da es beim Beenden der Funktion alles kopiert, was Sie zurückgeben. Das Ironische ist, dass der Compiler dies normalerweise tatsächlich optimiert (dh am Ende wird nichts kopiert, der Rückgabewert wird an der Adresse der eventuellen Zuweisung erstellt). Aber das hat nichts damit zu tun, warum wir es unkopierbar gemacht haben. Wenn Sie von einer Funktion zurückkehren, verschieben Sie das Objekt einfach vom inneren Funktionsumfang nach außen. Sie können jetzt Objekte schreiben, die nicht kopierbar, aber beweglich sind, und diese Objekte können von Funktionen zurückgegeben werden.
Die Verschiebungssemantik erleichtert das Schreiben von Code, der nicht ausläuft und threadsicher ist.
quelle