Wie bist du zu einem Konstanten-Korrektheitskonverter geworden? [geschlossen]

25

Nach 15 Jahren C ++ habe ich immer noch nicht gelernt, const zu lieben. Ich verstehe, dass es nützlich ist, aber ich war noch nie in einer Situation, in der das Problem, mit dem ich konfrontiert war, vermieden worden wäre , wenn ich die richtigen Konstanten hatte.

Wie sind Sie dazu gekommen, die Vorteile von Consts zu lieben?

grok
quelle
3
Ich denke, dass konstante Korrektheit mehr bedeutet, korrekt zu sein als ein Werkzeug, um ein Problem zu lösen, wie z. B. eine If Constrcut oder eine Sizeof Operator.
legends2k
9
"Der Grund, warum const in C ++ funktioniert, ist, dass Sie es wegwerfen können. Wenn Sie es nicht wegwerfen könnten, wäre Ihre Welt zum Kotzen." - Anders Hejlsberg
Mason Wheeler
1
const ist ebenfalls ein Modifikator vom Typ C und seit dem ersten ANSI-C-Standard.
Huperniketes
Durch Java / C # verwöhnt, bin ich ein paranoider Typ, der es liebt, behauptet, jede Chance zu haben, die ich bekomme. Was schief gehen kann, wird schief gehen. Wenn es eine Kompilierungszeit oder eine Laufzeitunterstützung gibt, dann zähle mich mit! Ich wurde ein Konverter, sobald ich 3-4 Mal davon hörte, und folgte einem Teil dieses Links (genug, um die Syntax zu sehen, ich brauchte nicht über das Warum zu lesen): possible.com/Cpp/const.html Nur weil noch nichts in meinem Gesicht explodiert ist ... braucht es wenig Mühe, um richtig zu sein, und es tut nicht weh. Informieren
Job

Antworten:

28

Nun, ich war nicht überzeugt, bis ich versuchte, die Philosophie anzunehmen.

Zunächst habe ich constmich an schreibgeschützte Member meiner grundlegendsten Argumente für Klassenmember und Memberfunktionen gewandt.

Von dort konnte ich nicht mehr kompilieren. Dann ging ich beharrlich mit diesen Basisklassen in den Code und überprüfte, ob die zuvor vorgenommenen constErgänzungen im Vergleich zu meiner Verwendung wirklich legitim waren. Es hat mir geholfen, einige Fehler auf dem Weg zu beheben, als ich anderen Teilen des Codes Konstanz verlieh.

Es ist ansteckend. Der Großteil des Codes wurde noch konsistenter und ich fand es einfacher, ihn zu debuggen, da Sie sicher sind, dass der Compiler Sie anhält, wenn Sie etwas ändern, das Sie nicht sollten.

Sobald ich die Anwendung wieder zum Laufen brachte, war sie schneller (ich musste einige Algorithmen ändern, von denen ich herausgefunden habe, dass sie nicht für den Job geeignet sind), mit viel weniger Fehlern und einfacher zu verstehen, wenn ich den Code lese.

Ich war überzeugt.

Jetzt denke ich, dass es noch besser ist, wenn Sie neben der Konstanz auch viele andere Behauptungen verwenden, da Sie sich sicher fühlen, wenn Sie neuen Code schreiben oder den aktuellen Code ändern müssen. Sie wissen, dass der Compiler Sie bei Bedarf anhält. Sie müssen nicht mehr alles überprüfen, was Sie nicht ändern sollten, und haben dann mehr Bedenkzeit für mehr geschäftsspezifisches Denken oder architektonisches Denken.

Klaim
quelle
8
+1 für ansteckend, was im Wesentlichen bedeutet, dass Sie entweder ein Konstanten-Konverter werden müssen oder es vollständig vermeiden müssen.
Martin Wickman
Sie müssen sich auch nicht auf Bibliotheken verlassen, die keine konstante Korrektheit bieten. Ihr Ansatz funktioniert nicht, wenn Sie keine der GUI-Funktionen aufrufen können, weil sie nicht const sind - oder Sie müssen sie bei jedem GUI-Aufruf verwerfen.
Martin Beckett
4
+1 für "fand es einfacher zu debuggen", verwende ich constauch für lokale Variablen, von denen ich weiß, dass sie nicht geändert werden müssen. Auf diese Weise kann ich beim Lesen von Code ein ifoder ein foroder was auch immer überfliegen: Meine Variable ist eine Konstante, ich Weiß, es wird sich nicht ändern! Ich könnte mich nicht weniger um Optimierungen kümmern, aber ich habe ein begrenztes Gehirn, und ein paar Einrückungen + Konstanten-Korrektheit helfen sehr!
Matthieu M.
@MatthieuM .: Schon mal darüber nachgedacht, zu Haskell zu wechseln? ;-)
Giorgio
@ Giorgio: Ich habe es ausprobiert und sogar "Real World Haskell" gekauft. Um ehrlich zu sein, ich bin nicht begeistert von Faulheit und den vielen kryptischen Operatoren, die aufgetaucht sind.
Matthieu M.
15

Ich war noch nie ein Befürworter der objektorientierten Programmierung, und wenn überhaupt, bin ich umso weniger gewachsen, je mehr ich über das Programmieren im Allgemeinen lerne. Als ich mich mit verschiedenen Programmierparadigmen befasst habe, wurde mir klar, dass Unveränderlichkeit eines der zentralen Konzepte des Programmdesigns ist, das sich auf Software auswirkt, die nach einer beliebigen Philosophie geschrieben wurde. Dies ist bei der funktionalen Programmierung von enormer Bedeutung. Dies hat Auswirkungen auf die Optimierung und die Parallelität, zusätzlich zu den einfachen Sicherheitsgarantien.

Grundsätzlich sollte alles, was unveränderlich sein kann, wahrscheinlich sein, es sei denn, Sie haben einen guten Grund für einen veränderlichen Zustand. Meiner Erfahrung nach führt das Schreiben von Programmen in einer beliebigen Sprache, um dieses Ziel zu erreichen, zu sichererem und besserem Code. Sie haben nichts zu verlieren, wenn Sie es verwenden const- die Unveränderlichkeit ist kostenlos!

(Im Übrigen habe ich mit der Idee gespielt, einen Fork von GCC für einen Dialekt von C ++ zu erstellen, in dem alle Typen verwendet werden, es constsei denn, dies wird ausdrücklich als qualifiziert mutable. Wenn es Unterstützung für so etwas gibt, werde ich mich voll und ganz verpflichten, ihn zu pflegen und zu verwenden.)


Vom OO-Standpunkt aus erzwingt die Unveränderlichkeit die Kapselung, indem ein uneingeschränkter Schreibzugriff verhindert wird. Dies verringert die Kopplung zwischen Klassen, da unveränderliche Objekte ihren eigenen Zustand vollständig verwalten und sich daher wie gewöhnliche Werte verhalten müssen. Die Konstanten-Korrektheit erleichtert den Nachweis der Programmkorrektheit erheblich, insbesondere im Zusammenhang mit der gleichzeitigen Programmierung. Mit der C ++ - Referenz- und der C ++ - R-Wert-Referenzsemantik können Sie unveränderliche Objekte verwenden, ohne sich Gedanken über den Aufwand machen zu müssen, sie überall zu kopieren. Darüber hinaus kann der Compiler einige erstaunliche Optimierungsmagie ausführen, wenn Sie mit größtenteils unveränderlichen Objekten arbeiten.

Ich weiß, es ist scheiße, constüberall zu tippen , aber man gewöhnt sich schnell daran und die Vorteile werden im Laufe der Zeit in Bezug auf Zuverlässigkeit und Wartbarkeit deutlich. Ich bin kein brillanter Schriftsteller, und es scheint eine erwiesene schwierige Aufgabe zu sein, dafür einzutreten, aber ich weiß, dass die Konstanten-Korrektheit für mich als Entwickler beim Entwerfen und Implementieren von Programmen immens hilfreich war, und ich denke, dass dies Erfahrung ist der beste Lehrer in dieser Hinsicht.

Jon Purdy
quelle
2
Sie haben im Grunde nur gesagt, dass const Korrektheit eine gute Sache ist. Sie sagten, dies führe zu "sichererem, besserem Code". Kannst du sagen warum?
David Reis
Ich bin total im Unveränderlichkeitslager, meine Lieblingssprache ist Erlang. Aber ich würde argumentieren, dass die Unveränderlichkeit über const in C ++ nicht wirklich kostenlos ist. Es gibt Nachteile wie weniger lesbaren Code, const- und non-const-Versionen derselben Methode oder das Wegwerfen von const, weil "es einfach keine andere Wahl gab".
Grok
1
Ich würde raten, nicht nur zu verwenden mutable, da es eine klare Bedeutung in Bezug auf die Konstanten-Korrektheit hat. Dies bedeutet, dass sich dieses Datenobjekt auf eine Weise ändern kann, die sich nicht auf das Objektverhalten auswirkt, und Dinge wie das Zwischenspeichern von Antworten ermöglicht. Machen Sie ein anderes Schlüsselwort.
David Thornley
2
@ David Thornley: Aus Gründen der Konsistenz mutableist die logische Wahl. void alter(mutable Point&)Sinn macht, wie mutable int foofür eine lokale Variable, und keiner dieser Konflikte mit der vorhandenen Sprache oder der vorhandenen Verwendung von mutable. Auch Object mutable* mutablesieht unheimlich genug , um eine Warnung vor zu sein , ob es notwendig ist oder nicht vollständig entsprechen.
Jon Purdy
Wenn Sie jemals die Gabelung machen, ziehen Sie in Betracht, stattdessen CLang zu nehmen - sollte weniger schmerzhaft sein.
gf
6

Der Vorteil der konstanten Korrektheit besteht darin, dass dem Programm Disziplin auferlegt wird und es einfacher ist, über Teile des Programms nachzudenken.

Die Disziplin ist, dass Sie wissen müssen, wo sich etwas ändern könnte. Der entsprechende Vorteil besteht darin, dass Sie leichter erkennen können, was ein Codeteil bewirkt, wenn Sie erkennen, was den Status möglicherweise ändert.

David Thornley
quelle
1
"Programme müssen geschrieben werden, damit sie gelesen werden können, und nur im Übrigen, damit Maschinen ausgeführt werden können." - Abelson & Sussman, SICP
Brandon DuRette
4

Als const die Richtigkeit der Konstruktion richtig betont , die ich in der Nähe zu einem ähnlichen Problem zu behandeln, die nicht Guss Operatoren; Verwenden Sie also kein Cast und stellen Sie sicher, dass die Konstanten korrekt sind, und verwenden Sie nur wenig Mutables. All dies sind Hinweise, um zu messen, wie gut das Design ist, aber nicht die tatsächlichen Tools, um das vorliegende Gesamtproblem zu lösen.

PS: Ich war total überzeugt, constals ich die Korrektheit des Gebrauchs verstanden habe;)

legends2k
quelle
2

Ich sehe zwei Hauptgründe für das Schreiben von const-korrekten Code. Zum einen ist der Compiler Ihr Freund, und mit const können Sie sich vor möglichen Fehlern warnen lassen. Der zweite Grund ist, dass durch die Konstanten-Korrektheit der Code besser lesbar wird. Beispielsweise wissen Sie immer, welche Funktionsargumente Eingaben und welche Ausgaben sind. Sie wissen auch, welche Elementfunktionen das Objekt ändern und welche nicht. Sie kennen diese Dinge sofort, ohne den Code durchlesen zu müssen. Dies setzt natürlich eine sehr umsichtige Verwendung voraus const_cast.

Dima
quelle
2

Ich war ein Konvertit, sobald ich wusste, dass es möglich war. Vom Standpunkt eines „guten Programmierstils“ aus machte es für mich Sinn. Es gibt verschiedene Gründe, warum es eine gute Praxis ist, konstant zu sein:

  • Lesbarkeit und Verständnis. Wenn ich den Code einer anderen Person lese und eine Funktion eine const-Referenz als Parameter verwendet, weiß ich, dass der Parameter nur als schreibgeschützte Variable verwendet werden soll. Dies ist ein enormer Gewinn, insbesondere wenn es sich bei dem Code um eine Umgebung mit mehreren Threads handelt.
  • Der Compiler kann das const-Qualifikationsmerkmal verwenden, um seine Optimierungsdurchläufe zu unterstützen.
  • Angenommen, ich habe ein Objekt der Klasse A in einer Situation, in der ich nicht möchte, dass es sich ändert. Die einzigen Memberfunktionen, die für dieses Objekt aufgerufen werden können, sind const.
Sashang
quelle
2

So fassen Sie zwei Punkte zusammen, die in anderen Antworten behandelt wurden, und fügen Sie einen neuen hinzu:

  • constdokumentiert den Code für Benutzer Ihrer API. Es bildet einen Vertrag zwischen einer Funktion und ihrem Aufrufer, dass die Funktion ihre Parameter nicht ändert. (Bitte beachten Sie, dass const_casteine Funktion nicht in der Lage ist, ihren Parameter zu ändern, sondern diesen Parameter an andere Funktionen weitergibt, die ihre Parameter nicht ändern, aber die constAnnotation vergessen haben .) Dies ist auch innerhalb von functions / loop / etc nützlich, da es das Verständnis der Parameter erheblich erleichtert genauso wie eine Schleife invariant.

  • constdokumentiert dem Compiler Ihre Absicht. Fehler beim Kompilieren zu finden ist immer besser, als darauf zu warten, dass der Code ausgeführt wird.

  • constist notwendig für typsicheren Polymorphismus. Zeiger (in all ihren Formen, nicht nur rohe Zeiger) sind nur dann kovariant, wenn sie es sind const(Anmerkung: nicht dasselbe wie "Zeiger auf const"). Covarianz erfordert eine Nur-Lese-Schnittstelle, und Contravarianz erfordert eine Nur-Schreib-Schnittstelle.

Die zweite habe ich zuerst gelernt. Ich begann constnur mit dem Ziel von Zeiger- und Referenzparametern, bis ich die Vorteile des Erfassens von Fehlern früher erkannte und anfing, sie bei Einheimischen usw. zu verwenden.

Dann habe ich gelernt, dass die meisten #defines (in C ++) durch globale Konstanten ersetzt werden können, mit zusätzlichen Vorteilen der Typensicherheit. Also habe ich es dort auch benutzt.

Schließlich nahm ich an einem Kurs über Typsysteme und Lambda-Berechnung teil und lernte, dass constund Nicht- constTypen sich grundlegend unterscheiden (da sie unterschiedliche Operationen unterstützen), und seitdem habe ich noch nie darüber nachgedacht, C ++ - Code ohne viel Einsatz von zu schreiben const.

Ben Voigt
quelle
1

Hier sind meine 5 Cent von dem, was ich noch nicht erwähnt habe. Wenn Sie Variablen übergeben, möchten Sie nicht als Wert übergeben, es sei denn, Sie müssen dies wirklich tun, um zusätzliche Konstruktionen, Destruktionen und Kopien zu vermeiden. Wenn Sie also nicht wirklich nach Wert übergeben müssen und Referenzen überall verwenden, bedeutet dies eine erhebliche Leistungssteigerung, auch wenn Sie nicht beabsichtigen, den übergebenen Wert zu ändern. Aus diesem Grund müssen Sie dem Aufrufer mitteilen, was die Funktion nicht ändern wird, wenn Funktionen Verweise auf alle ihre Argumente enthalten.

Es ist das gleiche Prinzip, aber ich wollte nur einen praktischen Grund für die Verwendung von const hinzufügen.

Nikiforos Rotas
quelle