Qu'est-ce qu'une étoile double (p. Ex. NSError **)?
-
03-07-2019 - |
Question
Alors, j'ai vu ceci:
error:(NSError **)error
dans le document Apple. Pourquoi deux étoiles? Quelle est la signification?
La solution
Une "étoile double" est un pointeur sur un pointeur. Donc NSError **
est un pointeur sur un pointeur sur un objet de type NSError
. Cela vous permet essentiellement de retourner un objet d'erreur à partir de la fonction. Vous pouvez créer un pointeur sur un objet NSError
dans votre fonction (appelez-le * myError
), puis procédez comme suit:
*error = myError;
pour "retourner" cette erreur à l'appelant.
En réponse à un commentaire posté ci-dessous:
Vous ne pouvez pas simplement utiliser un NSError *
car en C, les paramètres de fonction sont passés par valeur , autrement dit, les valeurs sont copiées lorsqu'il est passé à une fonction. Pour illustrer cela, considérons cet extrait de code C:
void f(int x)
{
x = 4;
}
void g(void)
{
int y = 10;
f(y);
printf("%d\n", y); // Will output "10"
}
La réaffectation de x
dans f ()
n'affecte pas la valeur de l'argument en dehors de f ()
(dans g ( )
, par exemple).
De même, lorsqu'un pointeur est passé dans une fonction, sa valeur est copiée et la réattribution n'affectera pas la valeur en dehors de la fonction.
void f(int *x)
{
x = 10;
}
void g(void)
{
int y = 10;
int *z = &y;
printf("%p\n", z); // Will print the value of z, which is the address of y
f(z);
printf("%p\n", z); // The value of z has not changed!
}
Bien sûr, nous savons que nous pouvons modifier la valeur de ce que z
désigne assez facilement:
void f(int *x)
{
*x = 20;
}
void g(void)
{
int y = 10;
int *z = &y;
printf("%d\n", y); // Will print "10"
f(z);
printf("%d\n", y); // Will print "20"
}
Il va donc de soi que, pour changer la valeur de ce à quoi un NSError *
pointe, nous devons également passer un pointeur au pointeur.
Autres conseils
En C, tout est transmis valeur par valeur. Si vous voulez changer la valeur de quelque chose, vous en transmettez l'adresse (ce qui transmet la valeur de l'adresse mémoire). Si vous souhaitez modifier l'emplacement d'un pointeur, passez l'adresse du pointeur.
En C, une étoile double est un pointeur sur un pointeur. Il y a deux raisons à cela. La première est que le pointeur pourrait être sur un tableau de pointeurs. Une autre raison serait de passer un pointeur à une fonction, cette dernière modifiant le pointeur (similaire à un paramètre "out" dans d'autres langues).
La notation étoile double (**) n’est pas spécifique à l’initialisation d’une variable dans une classe. C'est simplement une double référence indirecte à un objet.
float myFloat; // an object
float *myFloatPtr; // a pointer to an object
float **myFloatPtrPtr; // a pointer to a pointer to an object
myFloat = 123.456; // initialize an object
myFloatPtr = &myFloat; // initialize a pointer to an object
myFloatPtrPtr = myFloatPtr; // initialize a pointer to a pointer to an object
myFloat; // refer to an object
*myFloatPtr; // refer to an object through a pointer
**myFloatPtrPtr; // refer to an object through a pointer to a pointer
*myFloatPtrPtr; // refer to the value of the pointer to the object
La notation avec double pointeur est utilisée lorsque l'appelant souhaite qu'un de ses propres pointeurs doive être modifié par un appel de fonction. L'adresse du pointeur, au lieu de l'adresse de l'objet, est transmise à la fonction.
Un exemple pourrait être l'utilisation d'une liste chaînée. L'appelant conserve un pointeur sur le premier nœud. L'appelant appelle des fonctions pour rechercher, ajouter et supprimer. Si ces opérations impliquent l'ajout ou la suppression du premier nœud, le pointeur de l'appelant doit être changé, pas le pointeur .next dans l'un des nœuds, et vous avez besoin de l'adresse du pointeur pour le faire.
S'il s'agit de quelque chose comme C, **
désigne un pointeur sur un pointeur.