En raison de la façon dont les objets Objective-C fonctionnent, constcesse d'être une application et commence à être une notation pour le programmeur. Considérez ce programme:
int f(const int x) {
return ++x;
}
int main(int argc, char *argv[]) {
@autoreleasepool {
int x = 3;
NSLog(@"%d", f(x));
}
return 0;
}
Cela ne compilera pas ici (j'utilise clang): le compilateur peut détecter la tentative de modification du type C primitif et émet une erreur. Mais maintenant, comparez-le avec ce programme:
NSMutableString *f2(const NSMutableString * const x) {
[x appendString: @" world!"];
return x;
}
int main(int argc, char *argv[]) {
@autoreleasepool {
NSMutableString *x = [@"Hello" mutableCopy];
NSLog(@"%@", f2(x));
}
return 0;
}
Même si la fonction reçoit un pointeur constant vers un objet constant, il est toujours possible de muter l'objet.
Dans la programmation orientée objet, la meilleure façon de faire respecter la nature constante d'un objet est de rendre cet objet immuable - c'est-à-dire de ne fournir aucune méthode pouvant changer son état. Imaginez que la fonction ci-dessus prenne un NSStringargument au lieu de NSMutableString, et que j'avais passé le littéral @"Hello"au lieu d'une copie mutable. Il n'y a maintenant, raisonnablement, aucune chance de muter l'objet transmis [*]. Objective-C ne dispose d' aucun moyen de faire respecter que si, à la différence constou les finalréférences d'objets dans d' autres langues OO.
À titre de comparaison, constfonctionne entièrement différemment en C ++. Si j'obtiens une constréférence à un objet C ++, je ne suis autorisé qu'à appeler des constfonctions membres sur cet objet. Ces fonctions préservent l' constétat de l'objet, soit en n'apportant aucune modification, soit en modifiant uniquement les variables membres qui ont été explicitement marquées mutablepar le concepteur de classe. Imaginez donc que j'avais un type MutableStringen C ++ équivalent à NSMutableStringObjective-C. L'équivalent de mon exemple ci-dessus ressemblerait à quelque chose comme:
MutableString& f3(const MutableString& x) {
x.appendString(" world!");
return x;
}
Cela ne compilera certainement pas: en plus de appendString()ne pas être une constopération, la fonction supprime le constqualificatif de la référence de type qui nécessite un const_cast.
[*] Je m'attends à ce qu'il y ait une manière déformée de le faire, mais maintenant nous sommes dans le royaume d'un programmeur essayant d'en saboter un autre en faisant des choses "intelligentes".