wann const und wann nicht?



  • moinsen
    ich habe mal eine design frage, wann sollte ich bei funktionen bei den rückgabewerten und bei den parametern const verwenden?? ich meine:

    int foot(int);
    //oder
    const int foo(int);
    // oder
    int foo(const int);
    // oder
    const int foo(const int);
    

    woran macht ihr das fest? gibt es vlt performance unterschiede? oder bestimmte "sicherheitsmasnahmen"? wann ist es eurer meinung nach angebracht const zu benutzen?
    danke schonmal



  • Performanceunterschiede gibt's keine.
    Das const ist nur eine zusätzliche Sicherheit, d.h. Wenn du einer Funktion einen Wert übergibst, und sie wird ihn nicht ändern, dann deklariere den Wert const. Wenn eine Memberfunktion den Status des Objekts nicht ändert, deklariere sie const.
    also

    class X
    {
    	public:
    		int f (const Y &YClass);	//verändert Y nicht, aber mögl. das Objekt
    		int f (const Y &YClass) const;	//verändert Y und das Objekt nicht.
    		int f (Y &YClass);	//verändert Y und das Objekt
    }
    

    Wenn man diese Regeln einhält, dann ist der Zweck klarer zu verstehen.



  • const immer nur dann wenn die fuktion, sei es z.B. innerhalb einer klasse, den übergegebenen wert nicht ändert wie es auch schon gesagt wurde.
    man soll in solchen fällen immer const verwenden da es einfach zum guten stil gehört und weil sich die compiler fehler dann leichter finden lassen.

    mfg SIDEX



  • und wie sieht das mit den rückgabewerten aus? wann sollten diese const sein?



  • Das macht eigentlich nur dann Sinn, wenn du Pointer oder Referenzen zurückgibst. Und im Fall von Pointern wirst du dann auch nicht den Pointer, sondern nur seinen Inhalt const deklarieren - e.g.

    class A {
      std::string const inhalt;
    public:
      std::string const &get_inhalt() const { return inhalt; }
    };
    


  • wieso wird dann (wo wir schon bei dem beispiel mit std::string sind^^) in der klasse basic_string im konstruktor für c string der pointer auf den c string als const übergeben, der basic_string im konstruktor für diesen (bzw. die referenz darauf) nicht?



  • Babbo schrieb:

    wieso wird dann (wo wir schon bei dem beispiel mit std::string sind^^) in der klasse basic_string im konstruktor für c string der pointer auf den c string als const übergeben

    Der Zeiger ist nicht const, es ist lediglich ein Zeiger auf const Elemente.

    Babbo schrieb:

    der basic_string im konstruktor für diesen (bzw. die referenz darauf) nicht

    Tja, da hast du wohl 'ne fehlerhafte Implementation, im Standard kann ich diesbezüglich jedenfalls nix finden.



  • Vielleicht hat das was mit reference counting oder COW zu tun.





  • Regel 2:
    Funktionen/Methoden die "Return by value" verwenden, sollten immer ein konstantes Objekt liefern.

    Ausnahme:
    Diese Regel gilt nicht für die primitiven Typen (wie char, int, double usw.)

    bleiben wir mal bei dem beispiel mit string (^^), warum wird denn in basic_string::substr() ein nicht konstantes objekt zurückgegeben? basic_string gehört doch nicht zu den primitiven.
    in basic_string::c_str() wiederum wird const '_Elem' * zurückgegeben, obwohl _Elem doch wohl (in den alleraller meisten fällen) ein priomitiver ty is (zb char oder wchar_t)
    nochmal ausdrücklich die frage ( 🙄 ) wann sollten rückgabe werte konstant sein und wann nicht?



  • subsstr-Rückgabe ist nicht konstant, da es eh ein neues Objekt ist, an dem Du dann rumschrauben darfst. Das const zu machen würde den Benutzer für manche Operationen nur zwingen noch ne Kopie zu ziehen. Bei c_str ist es aber so, daß wir einen Zeiger auf einen internen Buffer rausgeben. Den möchten wir natürlich nicht einfach so von außen verändern lassen. Daher das const.

    Also: const immer dann, wenn Du Handles auf Daten rausgibst, die nur zum Lesen, aber nicht zum schreiben gedacht sind. Wenn Du by value zurückgibst (fast) nie const. Weil Du sonst den Benutzer zwingst sich unter umständen ne zusätzliche Kopie bis er damit arbeiten kann.

    MfG Jester


Anmelden zum Antworten