Als unerfahrener C ++ - Programmierer gibt es einige Konstrukte, die für mich immer noch sehr dunkel aussehen. Eines davon ist const
. Sie können es an so vielen Orten und mit so vielen verschiedenen Effekten verwenden, dass es für Anfänger fast unmöglich ist, lebend herauszukommen. Wird ein C ++ - Guru einmal für immer die verschiedenen Verwendungszwecke erklären und ob und / oder warum sie nicht verwendet werden sollen?
129
Antworten:
Der Versuch, einige Verwendungen zu sammeln:
Binden Sie einige temporäre an Verweis auf const, um seine Lebensdauer zu verlängern. Die Referenz kann eine Basis sein - und der Destruktor muss nicht virtuell sein - der richtige Destruktor heißt immer noch:
Erklärung mit Code:
Dieser Trick wird in der Dienstprogrammklasse ScopeGuard von Alexandrescu verwendet. Sobald das temporäre Element den Gültigkeitsbereich verlässt, wird der Destruktor von Derived korrekt aufgerufen. Dem obigen Code fehlen einige kleine Details, aber das ist die große Sache.
Verwenden Sie const, um anderen Methoden mitzuteilen, dass der logische Status dieses Objekts nicht geändert wird.
Verwenden Sie const für Copy-on-Write-Klassen , damit der Compiler Ihnen bei der Entscheidung hilft, wann und wann Sie nicht kopieren müssen.
Erläuterung : Möglicherweise möchten Sie Daten freigeben, wenn Sie etwas kopieren, solange die Daten des ursprünglichen und des kopierten Objekts gleich bleiben. Sobald eines der Objekte Daten ändert, benötigen Sie jedoch zwei Versionen: eine für das Original und eine für die Kopie. Das heißt, Sie kopieren auf eine Schreiben in eines der Objekte, sodass beide jetzt ihre eigene Version haben.
Code verwenden :
Das obige Snippet druckt dieselbe Adresse auf meinem GCC, da die verwendete C ++ - Bibliothek eine Kopie beim Schreiben implementiert
std::string
. Obwohl beide Zeichenfolgen unterschiedliche Objekte sind, verwenden sie denselben Speicher für ihre Zeichenfolgendaten. Wenn Sieb
non-const machen, wird die non-const-Version von bevorzugt,operator[]
und GCC erstellt eine Kopie des Sicherungsspeicherpuffers, da wir ihn ändern könnten und er die Daten von nicht beeinflussen darfa
!Damit der Kopierkonstruktor Kopien von const-Objekten und temporären Objekten erstellt :
Zum Erstellen von Konstanten, die sich trivial nicht ändern können
Zum Übergeben beliebiger Objekte als Referenz anstelle von Wert - um möglicherweise teures oder unmögliches Übergeben von Nebenwerten zu verhindern
quelle
Es gibt wirklich zwei Hauptverwendungen von const in C ++.
Konstante Werte
Wenn ein Wert die Form einer Variablen, eines Elements oder eines Parameters hat, der während seiner Lebensdauer nicht geändert wird (oder nicht geändert werden sollte), sollten Sie ihn als const markieren. Dies hilft, Mutationen am Objekt zu verhindern. Zum Beispiel muss ich in der folgenden Funktion die übergebene Student-Instanz nicht ändern, damit ich sie als const markiere.
Warum würden Sie das tun? Es ist viel einfacher, über einen Algorithmus nachzudenken, wenn Sie wissen, dass sich die zugrunde liegenden Daten nicht ändern können. "const" hilft, garantiert aber nicht, dass dies erreicht wird.
Das Drucken von Daten auf cout erfordert natürlich nicht viel Nachdenken :)
Markieren einer Mitgliedsmethode als const
Im vorherigen Beispiel habe ich Student als const markiert. Aber woher wusste C ++, dass das Aufrufen der GetName () -Methode für Schüler das Objekt nicht mutieren würde? Die Antwort ist, dass die Methode als const markiert wurde.
Das Markieren einer Methode "const" bewirkt zwei Dinge. In erster Linie teilt es C ++ mit, dass diese Methode mein Objekt nicht mutiert. Die zweite Sache ist, dass alle Mitgliedsvariablen jetzt so behandelt werden, als ob sie als const markiert wären. Dies hilft, hindert Sie jedoch nicht daran, die Instanz Ihrer Klasse zu ändern.
Dies ist ein äußerst einfaches Beispiel, aber hoffentlich hilft es Ihnen bei der Beantwortung Ihrer Fragen.
quelle
Achten Sie darauf, den Unterschied zwischen diesen 4 Erklärungen zu verstehen:
Die folgenden 2 Deklarationen sind semantisch identisch. Sie können ändern, wohin ccp1 und ccp2 zeigen, aber Sie können nicht ändern, auf was sie zeigen.
Als nächstes ist der Zeiger const. Um sinnvoll zu sein, muss er initialisiert werden, um auf etwas zu zeigen. Sie können es nicht auf etwas anderes verweisen lassen, aber das, worauf es zeigt, kann geändert werden.
Schließlich kombinieren wir beide - so kann das Objekt, auf das gezeigt wird, nicht geändert werden, und der Zeiger kann nicht auf eine andere Stelle zeigen.
Die Spiralregel im Uhrzeigersinn kann dabei helfen, eine Deklaration zu entwirren http://c-faq.com/decl/spiral.anderson.html
quelle
Als kleine Anmerkung, wie ich hier lese , ist es nützlich, das zu bemerken
quelle