Frage zu ConstCorrectness



  • Hallo,

    nutzt man heute noch ConstCorrectness? Wenn ja, habe ich das richtig verstanden, dann man dann das Schlüsselwort const hinter jeder Methode schreibt die keine Membervariablen verändert und vor jedem Bezeichner in der Methodensignatur der sich im Methodenkörper nicht ändert?

    Dann noch eine Frage: Merkt der Compiler nicht von allein welche Methoden was und wie ändern und optimiert dahingehend? Oder ist das ConstCorrectness nur für die Nutzung der Klassen später da?



  • Ja, es wird und sollte noch oft benutzt werden.
    Es geht dabei nicht nur um Compileroptimierungen, sondern ob ein Programm überhaupt übersetzt werden kann, d.h. mit einer konstanten Referenz bzw. Zeiger können dann keine nicht-konstanten Methoden aufgerufen werden.

    Mehr Infos gibt es in Political const correctness sowie (in englisch) Const Correctness.



  • Ok, vielen Dank für die rasche Antwort.



  • @CppConst sagte in Frage zu ConstCorrectness:

    nutzt man heute noch ConstCorrectness?

    Natürlich! Mehr denn je!

    Wenn ja, habe ich das richtig verstanden, dann man dann das Schlüsselwort const hinter jeder Methode schreibt die keine Membervariablen verändert

    ja, weil du bei einem const-Objekt die Methode ansonsten nicht aufrufen könntest.

    und vor jedem Bezeichner in der Methodensignatur der sich im Methodenkörper nicht ändert?

    Nicht unbedingt. Wenn ich z.B. einen int-Parameter habe, mache ich den in der Signatur normalerweise nicht const, da es für den Aufrufer eh keinen Unterschied macht. Wenn es sich um einen Pointer- oder Referenzargument handelt, sieht die Sache anders aus. Dann natürlich const, wenn sinnvoll. Nicht-const hat dann semantisch für mich als Aufrufenden die Bedeutung, dass es sich um einen out-Parameter handelt oder dass meine Variable zumindest geändert werden kann.

    Also ich mache int foo(int whatever, const Object& o) const.

    Du brauchst insbesondere nicht "const int" zurückzugeben.

    Dann noch eine Frage: Merkt der Compiler nicht von allein welche Methoden was und wie ändern und optimiert dahingehend? Oder ist das ConstCorrectness nur für die Nutzung der Klassen später da?

    Es ist für den Programmierer, damit es einfacher ist herauszufinden, was wo geändert werden kann. Wenn eine Methode const ist, weißt du ohne in die Funktion reinzugucken schon, dass sich am State nichts ändert (jetzt mal von mutable abgesehen). Das macht es einfacher, Code zu beurteilen. Übrigens auch in vielen anderen Sprachen versucht man oft, möglichst viel const zu machen, auch wenn da oft bei Objekten nur die Referenz const ist und nicht der Inhalt.

    Im Wesentlichen ist es für dein Programm egal, ob du alle consts löscht. Es gibt allerdings Ausnahmen. So kann der Compiler bei einem const int i = 42; annehemen, dass sich der Wert nicht ändert, auch nicht, wenn irgendwo mit einem const_cast Schindluder getrieben wird. Und Arrays kannst du auch nur mit konstanten Längen erzeugen (zumindest wenn du pedantisch bist).



  • const ist weniger für den Compiler und mehr für den Entwickler.
    Wenn ich sehe dass eine Methode const ist, dann bedeutet das dass sie den logischen Zustand des Objekts nicht ändert. Das ist eine wichtige Info.

    Genau so bedeutet es dass die Funktion thread-safe ist in dem Sinn dass man sie aus mehreren Threads gleichzeitig mit dem selben Objekt aufrufen kann.

    Wo dann der Compiler ins Spiel kommt ist dass er dabei hilft dieses Versprechen auch einzuhalten. Indem er in vielen Fällen wo man versucht dieses Versprechen zu brechen einen Fehler generiert. (Nicht in allen Fällen, denn sobald Zeiger im Spiel sind wirkt das const nicht mehr dort wo man es bräuchte.)

    D.h. const ist quasi ein Dokumentationswerkzeug das direkt in die Sprache eingebaut ist.

    habe ich das richtig verstanden, dann man dann das Schlüsselwort const hinter jeder Methode schreibt die keine Membervariablen verändert

    Nicht ganz.

    Eine Methode ala

    void Foo::store(int value) {
        m_myValueStore->store(value);
    }
    

    könnte man const machen, da m_myValueStore selbst (der Zeiger) ja nicht verändert wird. Sollte man aber vermutlich nicht, da ...

    • der Inhalt von *m_myValueStore vermutlich mit zum logischen Zustand von Foo gezählt werden sollte und
    • die aufgerufene ValueStore::store Funktion vermutlich nicht thread-safe sein wird

    Jeder der beiden Punkte alleine wäre schon Grund die Methode nicht const zu machen.

    Weiters könnte es Fälle geben in denen man nicht garantieren will dass eine Funktion den logischen Zustand des Objekts nie ändern wird oder immer thread-safe sein wird - selbst wenn es im Moment so ist. Dann kann es Sinn machen das const wegzulassen um sich die Möglichkeit vorzubehalten später Änderungen machen zu können - ohne dass man dann viel Code ändern muss der die Funktion verwendet.

    Bei Parametern und lokalen Variablen ist es ähnlich: const hilft mir beim Lesen des Codes. Wenn ich sehe dass die Variable const ist, weiss ich dass sie später nicht mehr verändert wird.



  • Vielen Dank für die sehr ausführlichen Antworten.


Log in to reply