2016-05-09 1 views
1

Eh bien, je connais la fonctionnalité du membre de données const dans une classe C++.Utilisation de membre de données const en C++

Ce que je veux savoir est, le but de l'introduction d'un membre de données const dans une classe. Pourquoi quelqu'un va l'utiliser en écrivant un vrai logiciel? Quelles sont les utilisations réelles des membres de données const?

S'il vous plaît donnez-moi quelques exemples de la vie réelle avec des raisons.

EDIT: Je ne parle pas de static const membre de données. Je demande des cas d'utilisation réels où chaque objet aura une valeur const différente pour les mêmes données.

+8

Pour les invariants de classe qui sont déterminés au moment de la construction? –

+0

'constexpr statique double pi = 3.14 ....' –

+1

@ paper.plane pourriez-vous me donner un exemple concret quand vous avez besoin d'un membre de données que ce n'est pas const? Je dirais que const est par défaut et non const sont les exceptions –

Répondre

1

Il existe plusieurs cas. Le plus évident est un membre de données const statique. Ceux-ci sont utilisés comme des constantes scope:

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

Notez que dans C++ 11 et au-delà, constexpr fait habituellement plus de sens dans ces cas.

Ceci définit une constante typée et étendue à l'implémentation de la classe. Je suppose que ce n'était pas ce que vous demandiez, cependant. Le cas d'utilisation le plus intéressant concerne les valeurs qui sont différentes entre les instances de la classe, mais constantes tout au long de la durée de vie de la classe. Par exemple, supposons que vous ayez une implémentation RAID, où une configuration définit la largeur de la bande. Vous ne connaissez pas la largeur de bande au moment de la compilation, donc la construction ci-dessus ne vous aidera pas. Vous voulez cependant que la largeur reste constante tout au long de la durée de vie de la classe (peut-être que votre code ne sait pas comment gérer les changements de largeur de bande).

Dans ces cas, en marquant la valeur const et en la définissant dans le constructeur, vous pouvez garantir la durée de compilation que personne ne modifie cette valeur.

+0

Votre logique est légèrement défectueuse. Quelque chose peut être différent entre les instances de la classe même si c'est static constexpr, c'est-à-dire s'il a été initialisé à partir d'un argument template. En outre, partout où nous nous attendons à voir 'static const' serait' static constexpr' (constexpr implique const). Une variable 'const 'publique n'a aucune raison de ne pas être' static constexpr' non plus. –

+0

Je ne considère pas différentes instanciations d'une classe comme "la même classe" (ni le compilateur). En ce qui concerne le deuxième commentaire, vous voulez parfois un const "global" qui est uniquement calculable au moment de l'exécution (comme la quantité totale de mémoire). Je suis d'accord que souvent Constexpr a un sens, et va modifier la réponse –

2

Vous utiliseriez un membre de données const pour la même raison que vous utiliseriez toutconst objet: pour une valeur qui peut être arbitrairement initialisés mais jamais changé. Une bonne règle empirique consiste à indiquer quelque chose comme const "par défaut", donc vous pouvez imaginer beaucoup de raisons de l'utiliser dans une classe.

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; 
}; 

Pouvez-vous omettre le const ici? Oui bien sûr. Mais alors vous pouvez accidentellement changer name quand vous ne vouliez pas. L'objectif entier de const est de se protéger contre de tels accidents.

Cependant, malheureusement, votre classe ne sera pas assignable!

+0

Oui, c'est un bon exemple. Ainsi, chaque fois que vous avez besoin d'une correction dans votre nom qui a été mentionnée à tort dans vos relevés bancaires, vous appelez le service client, puis créez un autre objet avec le nom correct dans le constructeur et appelez l'opérateur d'affectation avec l'ancien objet. objet. –

+0

@ paper.plane: Eh bien, si changer le nom est légal et valide dans votre logique métier, alors vous n'utilisez pas 'const'. Un "numéro de client" devrait probablement être "const" cependant. –

+0

Je suis d'accord avec votre remarque @Lightness, mais je demande simplement si la mise en œuvre est correcte lorsqu'une modification est nécessaire, étant donné que les changements de noms sont autorisés. –

0

Vous utilisez exactement la même chose que vous utiliseriez une const déclarée globalement, que vous voulez appliquer uniquement à la classe que vous avez défini. Par exemple

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; 
}; 

Il y a beaucoup d'autres exemples, mais le point principal est que nous ne voulons pas que TOTAL_HEALTH et TOTAL_MANA soient définis en dehors de la classe, car ils ne seront pas pertinents.