Dies betrifft hauptsächlich die zweite Zeile: Best Practices, Zuweisungen, Funktionsparameter usw.
Allgemeine Übung. Versuche alles zu machenconst
du kannst. Oder anders ausgedrückt: Machen Sie zunächst alles const
und entfernen Sie dann genau die Mindestmenge an const
s, die erforderlich ist, damit das Programm funktioniert. Dies ist eine große Hilfe bei der Erreichung der Konstanz und stellt sicher, dass keine subtilen Fehler auftreten, wenn Leute versuchen, Dinge zuzuweisen, die sie nicht ändern sollen.
Vermeiden Sie const_cast <> wie die Pest. Es gibt ein oder zwei legitime Anwendungsfälle dafür, aber es gibt nur sehr wenige. Wenn Sie versuchen, a zu ändernconst
Objekt , sollten Sie viel besser herausfinden, wer es const
im ersten Tempo deklariert hat , und die Angelegenheit mit ihm besprechen, um einen Konsens darüber zu erzielen, was passieren soll.
Was sehr ordentlich zu Aufgaben führt. Sie können etwas nur zuweisen, wenn es nicht konstant ist. Wenn Sie etwas zuweisen möchten, das const ist, siehe oben. Denken Sie daran, dass in den Erklärungen int const *foo;
undint * const bar;
verschiedenen Dingen const
- andere Antworten hier haben dieses Thema bewundernswert behandelt, so dass ich nicht darauf eingehen werde.
Funktionsparameter:
Wert übergeben: zB ist es void func(int param)
Ihnen am anrufenden Standort egal, auf welche Weise oder auf welche Weise. Es kann argumentiert werden, dass es Anwendungsfälle für die Deklaration der Funktion als gibtvoid func(int const param)
, die jedoch keine Auswirkungen auf den Aufrufer haben, sondern nur auf die Funktion selbst, da der übergebene Wert von der Funktion während des Aufrufs nicht geändert werden kann.
Als Referenz übergeben: zB void func(int ¶m)
Jetzt macht es einen Unterschied. Wie gerade erklärt, func
darf sich das ändern param
, und jeder anrufende Standort sollte bereit sein, mit den Konsequenzen umzugehen. Wenn Sie die Erklärung void func(int const ¶m)
ändern, um den Vertrag zu ändern, und Garantien, func
die sich jetzt nicht ändern können param
, bedeutet dies, dass das, was übergeben wird, wieder herauskommt. Wie andere angemerkt haben, ist dies sehr nützlich, um ein großes Objekt, das Sie nicht ändern möchten, kostengünstig zu übergeben. Das Übergeben einer Referenz ist viel billiger als das Übergeben eines großen Objekts nach Wert.
Pass by Pointer: zB void func(int *param)
und void func(int const *param)
Diese beiden sind so ziemlich gleichbedeutend mit ihren Referenzgegenstücken, mit der Einschränkung, dass die aufgerufene Funktion jetzt prüfen muss, es nullptr
sei denn, eine andere vertragliche Garantie stellt sicher, func
dass sie niemals ein nullptr
In erhält param
.
Meinungsbeitrag zu diesem Thema. In einem solchen Fall die Richtigkeit zu beweisen, ist höllisch schwierig, es ist einfach zu einfach, einen Fehler zu machen. Gehen Sie also kein Risiko ein und überprüfen Sie immer die Zeigerparameter auf nullptr
. Sie ersparen sich Schmerzen und Leiden und sind auf lange Sicht schwer zu finden. Und was die Kosten für die Prüfung angeht, ist sie spottbillig, und in Fällen, in denen die im Compiler integrierte statische Analyse sie verwalten kann, wird sie vom Optimierer trotzdem entfernt. Wenn Sie die Link Time Code-Generierung für MSVC oder WOPR (glaube ich) für GCC aktivieren, erhalten Sie sie programmweit, dh auch bei Funktionsaufrufen, die eine Quellcodemodulgrenze überschreiten.
Letztendlich ist all das ein sehr solides Argument, um immer Verweise auf Zeiger zu bevorzugen. Sie sind einfach rundum sicherer.