2010-01-28 8 views
17

Ich habe eine Menge Verwendungen des const-Schlüsselwortes nach Funktionen in Klassen gesehen, also wollte ich wissen, worum es ging. Ich lese hier etwas auf: http://duramecho.com/ComputerInformation/WhyHowCppConst.html.Mit 'const' in Klassenfunktionen

Es besagt, dass const verwendet wird, weil die Funktion "versuchen kann, alle Elementvariablen im Objekt zu ändern". Wenn das wahr ist, dann sollte es überall verwendet werden, weil ich nicht möchte, dass irgendeine der Mitgliedsvariablen in irgendeiner Weise verändert oder verändert wird.

class Class2 
{ void Method1() const; 
    int MemberVariable1;} 

Also, was ist die echte Definition und Verwendung von const?

+3

Wenn sich Ihre Elementvariablen nie ändern, warum haben Sie Membervariablen? –

+6

Weil er eine Klasse wollen, die unveränderlich ist? Das ist nicht unvernünftig. –

+1

Ich bin nicht wirklich eine C++ Person, also war es eher eine Frage von Interesse als eine "Gotcha" -Frage. Warum würdest du nicht einfach alle deine Mitglieder für "const" erklären, wenn du willst, dass es wirklich unveränderlich ist? Oder würden Sie beide die Mitglieder als const und die Methoden als const bezeichnen? –

Antwort

29

kann eine konstante Methode auf ein konstantes Objekt aufgerufen werden:

class CL2 
{ 
public: 
    void const_method() const; 
    void method(); 

private: 
    int x; 
}; 


const CL2 co; 
CL2 o; 

co.const_method(); // legal 
co.method();  // illegal, can't call regular method on const object 
o.const_method(); // legal, can call const method on a regulard object 
o.method();   // legal 
Außerdem

, es weist den Compiler auch, dass die konstante Methode nicht den Zustand des Objekts zu ändern und diese Probleme fangen werden sollten:

Es gibt eine Ausnahme von der oben genannten Regel, indem Sie den Modifizierer mutable verwenden, aber Sie sollten zuerst die Korrektheit der Korrektheit überprüfen, bevor Sie sich in dieses Gebiet wagen.

+0

Soll also für die Sicherheit const für alle Methoden zur Verfügung stehen, die den Zustand des Objekts nicht ändern sollen? (Getter, zum Beispiel) – gen

+0

Für const Korrektheit, ja. – U007D

1

Wenn das stimmt, sollte es dann überall verwendet werden, weil ich nicht möchte, dass irgendeine der Mitgliedsvariablen in irgendeiner Weise geändert oder geändert wird?

Nun, nein. Manchmal Sie tun wollen Instanz Methoden, um Mitglieder zu ändern. Zum Beispiel muss jede set-Methode natürlich Variablen setzen, also sollten Sie const nicht überall setzen. Aber wenn der Zustand Ihres Objekts völlig unveränderlich ist, überlegen Sie zuerst, ob es nicht besser ist, überhaupt keine Instanzen zu haben (d. H. Eine statische Klasse), und wenn das nicht der Fall ist, dann machen Sie alles const.

2

Die Bedeutung ist, dass Sie Clients, die ein const-Funktionsmember aufrufen, garantieren, dass sich der Status des Objekts nicht ändert. Wenn Sie also sagen, dass eine Elementfunktion const ist, bedeutet dies, dass Sie während des Funktionsaufrufs keine der Objektelementvariablen ändern.

+0

Das ist nicht ganz wahr - beobachtbares Verhalten ändert sich nicht, aber Mitgliedsdaten können, wenn sie als "veränderbar" gekennzeichnet sind. So können beispielsweise einmal berechnete Ergebnisse zwischengespeichert werden. –

+0

Es ist noch schlimmer. Wenn Sie einen Zeiger auf einige Daten zeigen, garantiert das "const" hinter einer Elementfunktion nur, dass der Zeiger nicht geändert wird, nicht die Daten, auf die er zeigt. Oft werden die Daten jedoch als Teil des Objektstatus betrachtet. Tatsächlich verhindert das "const" nur, dass eine Elementfunktion die Elementdaten des Objekts und nicht seinen gesamten Status ändert. Es erzwingt bitweise Konstanz, nicht logische Konstanz. – sbi

+0

In der Tat, es erzwingt nur bitweise Konstanz, und alle Wetten sind deaktiviert, wenn Sie ein Mitglied veränderlich setzen. Es ist nur ein Hinweis für den Compiler, Herr Klatchko hat oben eine bessere Erklärung. – mikelong

2

Es ist ziemlich ungewöhnlich, keine Elementvariablen geändert zu haben, aber wenn das Ihre Klasse erfordert, sollten Sie alle Ihre Elementfunktionen konstant machen.

aber Sie wahrscheinlich zumindest einige Mitglieder wollen sich ändern:

class A { 
    private: 
    int val; 
    public: 
    A() : val(0) {} 
    void Inc() { val++; } 
    int GetVal() const { return val; }; 
}; 

Nun, wenn ich zwei Instanzen von A zu erstellen:

A a1; 
const A a2; 

ich sagen kann:

a1.GetVal(); 
a2.GetVal(); 

aber ich kann nur sagen:

a1.Inc(); 

versuchen, den Wert eines konstanten Objekts zu ändern:

a2.Inc(); 

gibt einen Übersetzungsfehler.

+0

Methoden, die den externen Zustand nicht ändern, sind häufiger bei der deklarativen Programmierung - zugegebenermaßen nicht die einfachste Sache in C++. Aber flüssigere C++ - Bibliotheksdesigns sind auf dem Weg (z. B. [Ranges v3] (https://github.com/ericnebler/range-v3)), was dies in der Zukunft praktischer macht. – U007D

1

Das nach einer Methode verwendete Schlüsselwort const zeigt an, dass diese Methode das Objekt, an dem es aufgerufen wird, nicht ändert. Auf diese Weise kann diese Methode für eine konstante Version des Objekts aufgerufen werden.

3

const, wenn an eine nicht statische Klassenmethode angehängt, teilt dem Compiler mit, dass Ihre Funktion den internen Zustand des Objekts nicht ändert.

Dies ist auf zwei Arten nützlich:

  • Wenn Sie Code schreiben Sie die in Ihrem const Methode internen Zustand ändert, der Compiler den Fehler fängt, einen Programmierfehler von der Laufzeit bewegt zu Zeit zu kompilieren.
  • Wenn Client-Code eine nichtkonstante Methode für einen konstanten Zeiger aufruft, fängt der Compiler den Fehler ab und stellt sicher, dass die "Kette der Dinge nicht geändert wird" beibehalten wird.

Normalerweise möchten Sie alle nicht-mutierenden nicht statischen Klassenmethoden als const deklarieren. Dadurch kann der Aufrufcode das const-Qualifikationsmerkmal für Zeiger verwenden, und es hilft, Fehler zu finden.

Typisch C++: Sie können eine Klassenmitgliedsvariable "veränderbar" deklarieren und dann sogar von einer Konst-Methode ändern.

3

Andere haben die technische Seite Ihrer Frage zu const-Member-Funktionen beantwortet, aber es gibt ein größeres Bild hier - und das ist die Idee von const correctness.

Kurz gesagt, const Korrektheit geht es um die Klärung und Durchsetzung der Semantik Ihres Codes. Nehmen Sie ein einfaches Beispiel. Sehen Sie sich diese Funktionserklärung an:

bool DoTheThing(char* message); 

Angenommen jemand anderes hat diese Funktion geschrieben und Sie müssen sie aufrufen. Weißt du, was DoTheThing() mit deinem Char-Puffer macht? Vielleicht protokolliert es nur die Nachricht in einer Datei oder ändert die Zeichenfolge. Sie können nicht sagen, was die Semantik des Aufrufs ist, indem Sie nur die Funktionsdeklaration betrachten. Wenn die Funktion die Zeichenfolge nicht ändert, ist die Deklaration inkorrekt.

Es ist praktisch, die Funktionen auch korrekt zu konfigurieren. Je nach Kontext des Aufrufs können Sie möglicherweise keine const-incorrect-Funktionen aufrufen, ohne etwas zu tricksen. Zum Beispiel davon ausgehen, dass Sie wissen, dass DoTheThing() nicht den Inhalt der Zeichenfolge an sie übergeben nicht verändert, und Sie haben diesen Code:

void MyFunction() 
{ 
    std::string msg = "Hello, const correctness"; 
    DoTheThing(msg.c_str()); 
} 

Der obige Code wird nicht kompiliert, da msg.c_str() eine const char* zurückgibt. Um diesen Code zu kompilieren, würden Sie so etwas zu tun haben:

void MyFunction() 
{ 
    std::string msg = "Hello, const correctness"; 
    DoTheThing(msg.begin()); 
} 

... oder noch schlimmer:

void MyFunction() 
{ 
    std::string msg = "Hello, const correctness"; 
    DoTheThing(const_cast<char*>(msg.c_str())); 
} 

von denen keiner, wohl, sind ‚besser‘ als der ursprüngliche Code. Aber weil DoTheThing() in einer const-inkorrekten Weise geschrieben wurde, müssen Sie Ihren Code darum herum biegen.

Verwandte Themen