Comment «const» diffère-t-il en C et C ++?

Comment la qualification de const sur les variables diffère-t-elle en C et C ++?

from: Est – ce que “const” signifie seulement en lecture seule ou quelque chose de plus?

“Ce qui a motivé cette question, c’est cette réponse: https://stackoverflow.com/questions/4024318#4024417 où il déclare que” simplement “signifie en lecture seule dans le langage C. C ++. Que veut-il dire? ”

const en C ne peut pas être utilisé pour construire des expressions constantes.

Par exemple :

 #include  int main() { int i = 2; const int C = 2; switch(i) { case C : printf("Hello") ; break; default : printf("World"); } } 

ne fonctionne pas en C car l’étiquette de cas ne se réduit pas à une constante entière.

const signifie que vous promettez de ne pas muter la variable. Cela pourrait encore être changé.

 class A { public: A(const int& a); int getValue() const; void setValue(int b); private: const int& a; }; A::A(a) : a(a) {} int A::getValue() const { return a; } void A::setValue(int b) { a = b; // error } int main() { int my_a = 0; A a(my_a); std::cout << a.getValue() << std::endl; // prints 0 my_a = 42; std::cout << a.getValue() << std::endl; // prints 42 } 

Aucune méthode A::* peut changer a , mais le main peut. Cela est identique entre C et C ++.


Ce que C ++ a, ce sont deux manières (limitées) de contourner const , qui sont censées décourager les programmeurs de rejeter const manière inappropriée.

Prenez un cours comme celui-ci.

 class A { public: A(); int getValue(); private: static int expensiveComputation(); int cachedComputation; }; A::A() : cachedComputation(0) {} A::getValue() { if (cachedComputation == 0) cachedComputation = expensiveComputation(); return cachedComputation; } 

cachedComputation signifie implicitement cachedComputation this->cachedComputation . Garde ça en tête.

 int main() { A a1; const A a2; std::cout << a1.getValue() << std::endl; std::cout << a2.getValue() << std::endl; // error } 

a2.getValue() est illégale, car une méthode non const est appelée sur un const A a2 . On pourrait rejeter la const -ness…

  std::cout << ((A&)a2).getValue() << std::endl; // C-style cast std::cout << const_cast(a2).getValue() << std::endl; // C++-style cast 

La seconde est préférable, car le compilateur vérifiera que seule la const -ness est exprimée, rien d’autre. Cependant, ce n'est toujours pas idéal. Au lieu de cela, une nouvelle méthode devrait être ajoutée à la classe.

 class A { public: int getValue() const; }; A::getValue() const { if (cachedComputation == 0) cachedComputation = expensiveComputation(); // error return cachedComputation; } 

Maintenant, il existe une méthode const , donc a2.getValue() va bien. Cependant, le dernier const fin signifie que la méthode reçoit un const A *this pointeur, et non un A *this pointeur comme d'habitude, ce qui fait de this->cachedComputation un const int & ne pouvant pas être muté.

const_cast pourrait être appliqué à l'intérieur de la méthode, mais il serait préférable de changer la déclaration de ce membre.

 class A { private: mutable int cachedComputation; }; 

Maintenant, même avec un const A *this , this->cachedComputation peut être muté sans transtypage.