2016-05-09 26 views
1

Nun, ich kenne die Funktionalität von const Daten Mitglied in einer C++ - Klasse.Verwendung von const Datenelement in C++

Was ich wissen will, ist der Zweck der Einführung einer const Daten Mitglied in einer Klasse. Warum wird jemand das verwenden, während er eine echte Software schreibt? Was ist die tatsächliche Verwendung von const Datenmembern?

Bitte geben Sie mir ein paar reale Beispiele mit Gründen.

EDIT: Ich frage nicht nach static const Datenelement. Ich frage nach einigen realen Anwendungsfällen, bei denen jedes Objekt für dieselben Daten einen anderen konstanten Wert hat.

+8

Für Klassen Invarianten, die zur Konstruktionszeit bestimmt werden? –

+0

'constexpr statische Doppel-Pi = 3,14 ....' –

+1

@ paper.plane könnten Sie mir ein konkretes Beispiel geben, wenn Sie ein Datenelement haben müssen, dass es nicht const ist? Ich würde sagen, dass const ist standardmäßig und nicht const sind die Ausnahmen –

Antwort

1

Es gibt mehrere Fälle. Der offensichtlichste ist ein statisches const Datenelement. Diese werden als scoped Konstanten verwendet:

class Something { 
    static const int SOME_CONSTANT = 17; 
}; 

Beachten Sie, dass unter C++ 11 und weiter, constexpr Regel macht mehr Sinn, in diesen Fällen.

Dies definiert eine Konstante, die in die Klassenimplementierung eingegeben wird. Ich vermute, das war nicht das, was Sie gefragt haben.

Der interessantere Anwendungsfall ist für Werte, die sich zwischen Instanzen der Klasse unterscheiden, aber über die Lebensdauer der Klasse hinweg konstant sind.

Angenommen, Sie haben eine RAID-Implementierung, bei der eine Konfiguration die Stripe-Breite festlegt. Sie kennen die Streifenbreite zum Zeitpunkt der Kompilierung nicht, daher hilft Ihnen das obige Konstrukt nicht. Sie möchten jedoch, dass die Breite während der gesamten Lebensdauer der Klasse konstant bleibt (vielleicht weiß Ihr Code nicht, wie er mit Änderungen der Streifenbreite umgehen soll).

In diesen Fällen kann die Markierung des Werts const und die Festlegung im Konstruktor dazu führen, dass die Kompilierzeit garantiert wird, dass niemand diesen Wert ändert.

+0

Ihre Logik ist leicht fehlerhaft. Etwas kann zwischen Instanzen der Klasse auch dann anders sein, wenn es "statischer consxpr" ist, d. H. Wenn es aus einem Vorlagenargument initialisiert wurde. Darüber hinaus würden wir überall, wo wir erwarten, dass "statisch const" "statisch constexpr" wäre (constexpr bedeutet const). Eine öffentliche "const-Variable" hat auch keinen Grund, nicht "statisch constexpr" zu sein. –

+0

Ich halte verschiedene Instanziierungen einer Klasse nicht für "die gleiche Klasse" (und auch nicht für den Compiler). Wie für den zweiten Kommentar, manchmal wollen Sie eine "globale" Const, die nur zur Laufzeit (wie die Gesamtmenge des Speichers) berechenbar ist. Ich stimme zu, dass oft constexpr sinnvoll ist und die Antwort ändern wird –

2

Sie würden ein const Datenelement aus dem gleichen Grunde, die Sie jedesconst Objekt verwenden würden: für einen Wert, der dann aber nie geändert willkürlich initialisiert werden kann.

Eine gute Faustregel ist es, etwas als const "standardmäßig" zu bezeichnen, so dass Sie sich viele Gründe vorstellen können, es in einer Klasse zu verwenden.

class User 
{ 
    User(const std::string& name) 
     : name(name) 
    {} 

private: 
    /** 
    * User's name is an invariant for the lifetime of this object. 
    */ 
    const std::string name; 
}; 

Können Sie die const hier weglassen? Ja sicher. Aber dann können Sie versehentlich name ändern, wenn Sie nicht wollten. Der gesamte Zweck von const ist, vor solchen Unfällen zu schützen.

Leider ist Ihre Klasse leider nicht zuweisbar!

+0

Ja, das ist ein gutes Beispiel. Wenn Sie also eine Korrektur in Ihrem Namen benötigen, die fälschlicherweise in Ihren Bankunterlagen erwähnt wurde, rufen Sie die Kundenbetreuung auf und erstellen dann ein anderes Objekt mit dem korrekten Namen im Konstruktor und rufen den Zuweisungsoperator mit dem alten Objekt auf und löschen dann das alte Objekt. –

+0

@ paper.plane: Nun, wenn die Änderung des Namens in Ihrer Geschäftslogik zulässig und gültig ist, dann würden Sie 'const' nicht verwenden. Eine "Kundennummer" müsste wahrscheinlich "konst" sein. –

+0

Ich stimme Ihrem Punkt @Lightness zu, aber ich frage nur, ob die Implementierung richtig ist, wenn eine Änderung erforderlich ist, da Namensänderungen zulässig sind. –

0

Sie verwenden es genau das gleiche, wie Sie eine global deklariert const verwenden würde, nur wollen Sie es nur auf die Klasse anwenden Sie es in.

class Character 
{ 
public: 
    Character() 
    : 
     mCurrentHealth{TOTAL_HEALTH}, 
     mCurrentMana{TOTAL_MANA} 
    { 
    } 

    // Define lose/gain health/mana functions 
    // for mCurrentHealth and mCurrentMana 
private: 
    int mCurrentHealth; 
    int mCurrentMana; 

    // Constants 
    const int TOTAL_HEALTH = 100; 
    const int TOTAL_MANA = 50; 
}; 

Es gibt viele andere Beispiele Zum Beispiel definiert haben, aber der Hauptpunkt ist, dass wir TOTAL_HEALTH und TOTAL_MANA nicht außerhalb der Klasse definieren wollen, weil sie nicht relevant sind.

Verwandte Themen