Frage

Ich weiß, es gibt nur wenige Fragen zu const Korrektheit, wo es heißt, dass die Deklaration einer Funktion und ihrer Definition nicht für Wertparameter müssen zustimmen. Dies liegt daran, die Konstantheit eines Wertparameter nur innerhalb der Funktion zählt. Das ist in Ordnung:

// header
int func(int i);

// cpp
int func(const int i) {
    return i;
}

Tut dies wirklich eine beste Praxis? Weil ich nie jemand es tun gesehen habe. Ich habe dieses Zitat gesehen (nicht sicher von der Quelle) in anderen Orten, an dem diskutiert wurde:

  

„In der Tat, an den Compiler, die Funktionssignatur ist das gleiche, ob Sie diese const vor einem Wertparameter sind oder nicht.“

     

"Vermeiden konst Pass-by-value-Parameter in Funktionsdeklarationen. Noch die Parameter const in der gleichen Funktion Definition machen, wenn es nicht geändert werden."

Der zweite Absatz sagt nicht die const in der Erklärung zu setzen. Ich nehme an, das liegt daran, dass die Konstantheit eines Wertparameters als Teil einer Schnittstellendefinition bedeutungslos ist. Es ist eine Implementierung Detail.

Auf der Grundlage dieser Empfehlung ist es auch für die Zeigerwerte von Zeigerparametern zu empfehlen? (Es ist sinnlos, auf einen Referenzparameter, da Sie nicht eine Referenz zuweisen können.)

// header
int func1(int* i);
int func2(int* i);

// cpp
int func1(int* i) {
    int x = 0;

    *i = 3; // compiles without error
    i = &x; // compiles without error

    return *i;
}
int func2(int* const i) {
    int x = 0;

    *i = 3; // compiles without error
    i = &x; // compile error

    return *i;
}

Zusammenfassung: zu machen Wert Parameter ist nützlich, einige Logikfehler zu fangen. Ist es eine bewährte Methode? Gehst du auf die Spitze des const aus der Header-Datei zu verlassen? Ist es nur als nützlich, um const Zeigerwerte? Warum oder warum nicht?

Einige Referenzen:

C ++ Schlüsselwort const - Verwendung liberal Verwendung von 'const' für Funktionsparameter

Ein Beispiel, wenn konst Wertparameter sind nützlich:

bool are_ints_equal(const int i, const int j) {
    if (i = j) { // without the consts this would compile without error
        return true;
    } else {
        return false;
    }
    // return i = j; // I know it can be shortened
}
War es hilfreich?

Lösung

Mein Nehmen auf sie:

Es ist keine schlechte Idee, aber das Problem ist gering und Ihre Energie könnte besser für andere Dinge ausgegeben werden.

In Ihrer Frage, sofern Sie ein gutes Beispiel dafür, wenn es einen Fehler hängen bleiben könnte, aber gelegentlich auch Sie am Ende so etwas wie dies zu tun:

void foo(const int count ...)
{
   int temp = count;  // can't modify count, so we need a copy of it
   ++temp;

   /* ... */
}

Die Vor- und Nachteile sind kleinere oder so.

Andere Tipps

Ich habe oft gelesen, dass Wert machen Parameter in einer Funktion const eine schlechte Sache zu tun, weil es nicht notwendig ist.

Allerdings finde ich es mir gelegentlich hilfreich zur Kontrolle, dass meine Implementierung etwas nicht tut Ich beabsichtige nicht, (wie im Beispiel am Ende Ihrer Frage).

So, während es nicht Wert, der den Anrufer hinzufügen, ist es manchmal ein kleines bisschen Wert für mich als Implementierer hinzufügen, und es nimmt nichts weg von dem Anrufer. Also habe ich keinen Schaden mit ihm zu sehen.

Zum Beispiel kann ich eine C-Funktion implementieren, die ein paar Zeiger auf einen Puffer nimmt - einen Zeiger auf den Start, und einen Zeiger auf das Ende. Ich werde Daten im Puffer setzen, aber will, um sicherzustellen, dass ich nicht das Ende tun überrannt. So in der Funktion gibt es Code, der einen Zeiger erhöht wird, wie ich Daten darauf bin hinzufügen. Machen Sie den Zeiger auf das Ende des einen const Parameter Puffer wird dafür sorgen, dass ich auf einen Fehler nicht Code zu tun, dass versehentlich die Endbegrenzung Zeiger anstelle des Zeigers erhöht ich sollte wirklich erhöht wird.

So eine FillArray Funktion mit einer Signatur wie folgt aus:

size_t fillArray( data_t* pStart, data_t* const pEnd);

wird mich nicht versehentlich Inkrementieren pEnd wenn ich Schritt pStart wirklich bedeuten. Es ist keine große Sache, aber ich bin ziemlich sicher, dass jeder, der für einen beliebigen Zeitraum in C über eine solche Fehler ausgeführt wurde programmiert hat.

Leider sind einige Compiler (ich looking at you, Sun CC!) Unterscheiden falsch zwischen Argumenten erklärt const und Einsen nicht so deklariert, und Sie können Fehler über undefinierte Funktionen erhalten.

Ich denke, das auf Ihrem persönlichen Stil abhängig ist.

Es ist nicht zu addieren oder subtrahieren, was Kunden auf Ihre Funktion übergeben können. Im Grunde ist es wie eine Kompilierung-Behauptung. Wenn es hilft Ihnen, diesen Wert zu wissen, wird sich nicht ändern, gehen Sie voran und es tun, aber ich sehe keinen großen Grund für andere sehen, es zu tun.

Ein Grund, warum ich tun könnte dies nicht der Fall, dass die const-ness des Wertparameter ist eine Implementierung Detail, dass Ihre Kunden brauchen nicht darüber zu wissen. Wenn Sie später (absichtlich) Ihre Funktion ändern, so dass es tatsächlich ändern tut dieser Wert, müssen Sie die Signatur Ihrer Funktion ändern, was Ihre Kunden neu kompilieren zwingen wird.

Dies ist ähnlich, warum manche Menschen empfehlen, keine öffentlichen virtuelle Methoden mit (den Funktionen virtuell-ness ist eine Implementierung Detail, die von Kunden versteckt werden soll), aber ich bin nicht in diesem bestimmten Lager.

Wenn es const Schlüsselwort vorhanden; es bedeutet Wert von ‚i‘ (die const Typ ist) kann nicht verändert werden. Wenn der Wert von ‚i‘ innerhalb foo Funktion Compiler geändert wird, Fehler aus: „

  

Kann nicht ändern konstantes Objekt

Aber Ändern '* i' (d * i = 3;) Mittel Sie ändern Wert nicht von 'i', sondern Wert von Adresse wies die von 'i'

Eigentlich ist die konstante Funktion ist geeignet für große Objekte, die nicht durch die Funktion geändert werden soll.

Wir haben alle zu entwirren in einer anderen, C ++ Code von Zeit zu Zeit. Und dass jemand anderes ist C ++ Code ist ein komplettes Chaos per Definition:. D

So die erste Sache, die ich es immer tun, um zu entziffern (lokale und globale Datenfluss) wird gesetzt const in jeder Variablendefinition bis Compiler beschwert. Das bedeutet auch, const-Qualifikations-Wert Argumente, und es hilft wirklich Variablen vermieden werden, die auf die Funktion, ohne mich in der Mitte verändert wurden es zu merken ...

Also habe ich wirklich zu schätzen, wenn dass jemand anderes const überall hat (einschließlich Wertparameter): D

Ich mag const Korrektheit für Situationen wie diese:
void foo(const Bar &b) //I know b cannot be changed
{
//do something with b
}

Das lässt mich verwenden b ohne Angst, sie zu ändern, aber ich habe nicht die Kosten eines Copykonstruktor zu zahlen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top