Wann const?



  • Hey!

    Wie findet ihr es schöner? Immer const verwenden, wann man nur kann? zB wenn ich einem Objekt einen festen Namen gebe (ala std::string name), dann gleich const verwenden, weil der Name nie verändert wird? Oder doch lieber nur bei komplexeren Konstrukten, wo man sich eventuell vertun kann?

    MfG



  • const correctness ist keine frage des persönlichen geschmacks.



  • onst correctness ist keine frage des persönlichen geschmacks.

    Sehe ich genauso.
    Gruss Simon



  • const-correctness ist vor allem eine Frage von design by contract. Also immer dann const verwenden, wenn es richtig ist (also wenn objekte auch wirklich const sind)



  • Also wäre es Schwachsinn, hier ein const zu schreiben?

    Klasse::Klasse(const std::string text)
    {
        bla = text;
    }
    
    Klasse klasse("joah");
    
    // oder
    const std::string text = "joar";
    Klasse klasse(text);
    

    Dabei sollte ich das const im Konstruktor weglassen, richtig? Weil text ja sowieso ein kopiertes Objekt ist...

    MfG



  • Hier solltest du eh eine konstante Referenz übergeben.
    Ich verwende const wo es nur geht. Lediglich bei primitiven Datentypen, die by value übergeben werden, finde ich es Schwachsinn.



  • Also in dem Fall würde ich den parameter im Ctor nicht const machen. Wird eh kopiert und der User braucht sich um seinen übergebenen String keine Sorge machen, das er verändert wird.



  • hmm:

    Klasse::Klasse(const std::string text)
    {
        bla = text;
    }
    

    Hier wird ja den Wert eh kopiert(2x) und nachdem der Konstruktor verlassen wird text zerstört.

    foo::foo(std::string const& text) : m_text(text) {}
    

    Hier wird eine konstante Referenz übergeben. Der Wert wird NICHT kopiert.(bzw. nur in m_text)

    Klasse klasse("joah");
    
    // oder
    const std::string text = "joar";
    Klasse klasse(text);
    

    Hmm Werte, die eine bestimmte Aussage in einem Projekt haben, sollte man als Konstante hinterlagen, die einen ausschlaggebenden Namen haben.

    Und zu guter Letzt:
    http://www.parashift.com/c++-faq-lite/const-correctness.html



  • Jo.

    Aber warum eine Referenz? Das string-Objekt braucht doch beim Kopieren kaum mehr Resourcen als ne int, oder?

    MfG



  • Ehm doch? ^^



  • Bei paar Buchstaben...?



  • Alleine schon die Klasse belegt ne Menge Speicherplatz (die privaten Klassenmember und die Klassenmethoden brauchen auch was...)



  • ceplusplus@loggedoff schrieb:

    Aber warum eine Referenz? Das string-Objekt braucht doch beim Kopieren kaum mehr Resourcen als ne int, oder?

    ein int passt in ein register. ein string muss für die kopie konstruiert werden, was meistens eine allokation und speicherkopie bedeutet (ich lasse strategien wie cow mal außer acht). wenn ich es beziffern müsste, würde ich sagen, dass eine string-kopie mindestens einen 100000 mal größeren aufwand bedeutet als eine int-kopie (achtung: unseriöse schätzung)



  • Yay ok stimmt wohl, weiß ja ned wie groß die string-Klasse ist.

    MfG



  • Zurück zur Ursprungsfrage: In der Hinsicht mal ich Nemerle. In dieser Programmiersprache ist *jedes* Objekt 'const', es sei denn, es wird explizit als 'mutable' ausgegeben.

    Vergleichbar mit pur funktionalen Sprachen, wo ausnahmslos *alles* konstant ist.

    Dementsprechend gilt auch in C++: Überall dort 'const', wo es geht. Nur dort, wo es nicht möglich ist (Zählvariablen in Schleifen vor allem), wird es weggelassen. Zugegeben, Parameter deklariere ich auch nicht 'const', weil dies irgendwie zur Schnittstelle der Funktion gehört und daher sinnlos ist. Aber *eigentlich* ist es sehr wohl sinnvoll, damit man die Parameter nicht innerhalb der Funktion ändern kann (auch, wenn das nach außen eh keine Auswirkungen hätte).



  • ceplusplus@loggedoff schrieb:

    Also wäre es Schwachsinn, hier ein const zu schreiben?

    Klasse::Klasse(const std::string text)
    {
        bla = text;
    }
    

    ...

    Ich glaube, Du vergisst einen Effekt von diesem Konstrukt: Du kannst in der Implementation des Konstruktors den Wert von text nicht mehr ändern. Auch wenn diese Änderungen für den Aufrufer vermutlich ohne Konsequenzen bleiben dürfte (Achtung: static members nicht vergessen !), hat es immer noch den Vorteil, dass es Dich (als Implementierer) vor Fehlern bewahren kann.
    z.B. vor solchen:

    void MyClass::f(string s) {
       st = s; // st ist Member von MyClass
       st += "Simon2";
       cout << st;
       s += " noch was"; // Ooops, meinte eigentlich st
    }
    
    void MyClass::appendMsg(string s) { // Oops, meinte eigentlich string&
       s += st;
    }
    

    und - wie schon gesagt - sichert das const auch gegen Veränderungen von static members...

    Gruß,

    Simon2.



  • Simons Beispiel machts schon ein bissl deutlich: const-correctness allein ist nicht alles, es ist auch wichtig, Referenzen richtig zu gebracuhen oder eben nicht zu gebracuhen. Wenn ich einen Parameter per value übergebe, dann wohl nur, weil ich damit unabhängig vom Original weiterarbeiten will. Dafür sollte der Parameter dann allerdings nicht const sein. Wenn ich wiederum nichts am Parameter drehen möchte, reicht auch eine const Referenz um unnötiges Kopieren zu sparen. Ausgenommen sind builtins wie int, double & Co, wo das Anlegen einer Referenz ähnlich teuer sein kann wie eine Kopie, also übergebe ich die immer per value und schreib unter Umständen ein const ran, um mir zu merken dass ich den Wert nicht ändere.

    Alles weitere deckt das GotW das ich bone gelinkt hab denke ich sehr gut ab...


Anmelden zum Antworten