J'ai vu beaucoup d'utilisations du mot clé const après les fonctions dans les classes, donc je voulais savoir de quoi il s'agissait. J'ai lu smth ici: http://duramecho.com/ComputerInformation/WhyHowCppConst.html .
Il dit que const est utilisé parce que la fonction "peut tenter de modifier n'importe quelle variable membre dans l'objet". Si cela est vrai, alors devrait-il être utilisé partout, car je ne veux pas que TOUTES les variables membres soient altérées ou changées de quelque manière que ce soit.
class Class2
{ void Method1() const;
int MemberVariable1;}
Alors, quelle est la véritable définition et utilisation de const?
Une méthode const peut être appelée sur un objet const:
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
En outre, il indique également au compilateur que la méthode const ne doit pas modifier l'état de l'objet et détectera ces problèmes:
void CL2::const_method() const
{
x = 3; // illegal, can't modify a member in a const object
}
Il y a une exception à la règle ci-dessus en utilisant le modificateur mutable, mais vous devez d'abord obtenir une bonne constance avant de vous aventurer dans ce territoire.
D'autres ont répondu au côté technique de votre question sur les fonctions des membres const, mais il y a une image plus grande ici - et c'est l'idée de const correctness .
Pour faire court, la constance consiste à clarifier et à appliquer la sémantique de votre code. Prenons un exemple simple. Regardez cette déclaration de fonction:
bool DoTheThing(char* message);
Supposons que quelqu'un d'autre ait écrit cette fonction et que vous deviez l'appeler. Savez-vous ce que DoTheThing()
fait à votre tampon de caractères? Peut-être qu'il enregistre simplement le message dans un fichier, ou peut-être qu'il modifie la chaîne. Vous ne pouvez pas dire quelle est la sémantique de l'appel en regardant simplement la déclaration de fonction. Si la fonction ne modifie pas la chaîne, alors la déclaration est const incorrecte.
Il est également utile de rendre vos fonctions constantes. À savoir, selon le contexte de l'appel, il se peut que vous ne puissiez pas appeler des fonctions const-incorrectes sans une ruse. Par exemple, supposez que vous savez que DoTheThing()
ne modifie pas le contenu de la chaîne qui lui est passée et que vous avez ce code:
void MyFunction()
{
std::string msg = "Hello, const correctness";
DoTheThing(msg.c_str());
}
Le code ci-dessus ne se compilera pas car msg.c_str()
renvoie un const char*
. Pour obtenir ce code à compiler, vous devez faire quelque chose comme ceci:
void MyFunction()
{
std::string msg = "Hello, const correctness";
DoTheThing(msg.begin());
}
... ou pire encore:
void MyFunction()
{
std::string msg = "Hello, const correctness";
DoTheThing(const_cast<char*>(msg.c_str()));
}
aucun des deux, sans doute, n'est "meilleur" que le code d'origine. Mais parce que DoTheThing()
a été écrit d'une manière const-incorrecte, vous devez contourner votre code.
const, lorsqu'il est attaché à une méthode de classe non statique, indique au compilateur que votre fonction ne modifie pas l'état interne de l'objet.
Ceci est utile de deux manières:
En règle générale, vous souhaitez déclarer toutes les méthodes de classe non statiques non mutantes comme const. Cela permet au code appelant d'utiliser le qualificatif const sur les pointeurs et aide à détecter les erreurs.
C++ typique: vous pouvez déclarer une variable de membre de classe "mutable", puis la modifier même à partir d'une méthode const.
Cela signifie que vous garantissez aux clients appelant un membre de la fonction const que l'état de l'objet ne changera pas. Ainsi, lorsque vous dites qu'une fonction membre est const, cela signifie que vous ne modifiez aucune des variables membres des objets pendant l'appel de fonction.
Si cela est vrai, alors devrait-il être utilisé partout, parce que je ne veux AUCUNE des variables membres à être altérées ou changées de quelque façon?
Et bien non. Parfois, vous faites voulez que les méthodes d'instance modifient les membres. Par exemple, toute méthode set devra évidemment définir des variables, donc ce n'est pas le cas que vous devez mettre const partout. Mais si l'état de votre objet est totalement immuable, demandez-vous d'abord s'il ne vaut pas mieux n'avoir aucune instance (c'est-à-dire une classe statique), et si ce n'est pas le cas, faites tout const
.
Il est assez inhabituel de ne pas vouloir changer les variables membres, mais si c'est ce que votre classe requiert, alors vous devriez rendre constantes toutes vos fonctions membres.
Cependant, vous voulez probablement changer au moins certains membres:
class A {
private:
int val;
public:
A() : val(0) {}
void Inc() { val++; }
int GetVal() const { return val; };
};
Maintenant, si je crée deux instances de A:
A a1;
const A a2;
Je peux dire:
a1.GetVal();
a2.GetVal();
mais je peux seulement dire:
a1.Inc();
essayer de changer la valeur d'un objet constant:
a2.Inc();
donne une erreur de compilation.
Le mot clé const utilisé après une méthode indique que cette méthode ne modifie pas l'objet sur lequel elle est appelée. De cette façon, cette méthode peut être appelée sur une version const de l'objet.