Dans quelles circonstances pourriez-vous utiliser plusieurs indirections (c'est-à-dire, une chaîne de pointeurs comme dans Foo **
) en C++?A quoi sert l'indirection multiple en C++?
Répondre
L'utilisation la plus courante comme @aku a été signalée est de permettre à une modification d'un paramètre de pointeur d'être visible après le retour de la fonction.
#include <iostream>
using namespace std;
struct Foo {
int a;
};
void CreateFoo(Foo** p) {
*p = new Foo();
(*p)->a = 12;
}
int main(int argc, char* argv[])
{
Foo* p = NULL;
CreateFoo(&p);
cout << p->a << endl;
delete p;
return 0;
}
Cela imprime
12
Mais il y a plusieurs autres usages utiles comme dans l'exemple suivant pour itérer un tableau de chaînes et de les imprimer sur la sortie standard.
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
const char* words[] = { "first", "second", NULL };
for (const char** p = words; *p != NULL; ++p) {
cout << *p << endl;
}
return 0;
}
OMI utilisation la plus courante est de passer référence à pointeur variable de
void test(int ** var)
{
...
}
int *foo = ...
test(&foo);
Vous pouvez créer une matrice en dents de scie multidimensionnel en utilisant doubles pointeurs:
int ** array = new *int[2];
array[0] = new int[2];
array[1] = new int[3];
Si vous passez un pointeur dans le paramètre en sortie, vous peut vouloir le passer comme Foo**
et définir sa valeur comme *ppFoo = pSomeOtherFoo
. Et à partir du département structures d'algorithmes et de données, vous pouvez utiliser cette double indirection pour mettre à jour les pointeurs, ce qui peut être plus rapide que d'échanger des objets réels par exemple.
Un exemple simple utiliserait int** foo_mat
comme un tableau 2d d'entiers. Ou vous pouvez également utiliser des pointeurs vers des pointeurs - disons que vous avez un pointeur void* foo
et vous avez 2 objets différents qui ont une référence avec les membres suivants: void** foo_pointer1
et void** foo_pointer2
, en ayant un pointeur sur un pointeur que vous pouvez réellement vérifier si *foo_pointer1 == NULL
qui indique que foo est NULL. Vous ne seriez pas capable de vérifier si foo est NULL si foo_pointer1 était un pointeur régulier. J'espère que mon explication était pas trop en désordre :)
Habituellement, lorsque vous passez un pointeur vers une fonction en tant que valeur de retour:
ErrorCode AllocateObject (void **object);
où la fonction renvoie un code d'erreur succès/échec et remplissages dans le paramètre d'objet avec un pointeur vers le nouvel objet:
*object = new Object;
Ceci est beaucoup utilisé dans la programmation COM dans Win32.
Ceci est plus une chose C à faire, en C++, vous pouvez souvent envelopper ce type de système dans une classe pour rendre le code plus lisible.
Carl: Votre exemple devrait être: (. Vous avez deux étoiles)
*p = x;
:-)
Oh, ouais, vous avez raison. Fixe, merci! –
Un scénario commun est l'endroit où vous devez passer un pointeur null à une fonction, et l'avoir initialisé dans cette fonction, et utilisé en dehors de la fonction. Sans l'indirection multplie, la fonction appelante n'aurait jamais accès à l'objet initialisé.
Tenir compte de la fonction suivante:
initialize(foo* my_foo)
{
my_foo = new Foo();
}
Toute fonction qui appelle « initialisation (foo *) » auront pas accès à l'instance initialisées de Foo, beacuse le pointeur qui est passé à cette fonction est copie. (Le pointeur est juste un entier après tout, et les entiers sont passés par valeur.)
Cependant, si la fonction a été définie comme ceci:
initialize(foo** my_foo)
{
*my_foo = new Foo();
}
... et il a été appelé comme ça ...
Foo* my_foo;
initialize(&my_foo);
... alors que l'appelant aurait accès à l'instance initialisée, via 'my_foo' - parce que c'est l'adresse du pointeur qui a été passé à 'initialiser'. Bien sûr, dans mon exemple simplifié, la fonction 'initialize' pourrait simplement renvoyer l'instance nouvellement créée via le mot-clé return, mais cela ne convient pas toujours - peut-être que la fonction doit retourner quelque chose d'autre.
Vous pouvez également utiliser une référence ici (foo * &). Mais en dehors de cela, votre exemple est bon. –
En C, l'idiome est absolument nécessaire. Considérez le problème dans lequel vous voulez qu'une fonction ajoute une chaîne (pur C, donc un char *) à un tableau de pointeurs sur char *. Le prototype de la fonction nécessite trois niveaux d'indirection:
int AddStringToList(unsigned int *count_ptr, char ***list_ptr, const char *string_to_add);
Nous appelons comme suit:
unsigned int the_count = 0;
char **the_list = NULL;
AddStringToList(&the_count, &the_list, "The string I'm adding");
En C++, nous avons la possibilité d'utiliser des références à la place, ce qui donnerait une signature différente. Mais nous avons toujours besoin des deux niveaux d'indirection que vous avez demandés dans votre question initiale:
int AddStringToList(unsigned int &count_ptr, char **&list_ptr, const char *string_to_add);
- 1. A quoi sert vraiment EditorReuseAttribute?
- 2. À quoi sert __gxx_personality_v0?
- 3. À quoi sert MyAssembly.XmlSerializers.dll?
- 4. A quoi sert le N dans varchar (N)
- 5. System.Web.Abstractions: à quoi sert-il?
- 6. à quoi sert un manifeste?
- 7. Objective-C/Cocoa: A quoi sert l'objet proxy "Application" dans Interface Builder/Nib?
- 8. À quoi sert l'opérateur de substitution Perl?
- 9. À quoi sert la variable d'environnement XDG_SESSION_COOKIE?
- 10. $$ dans jQuery, à quoi cela sert-il?
- 11. À quoi sert Reflection dans .NET?
- 12. À quoi sert la propriété AppDomainSetup.SandboxInterop?
- 13. À quoi sert le dossier obj?
- 14. À quoi sert le paramètre Neutral Language?
- 15. À quoi sert "strip" (application GCC)?
- 16. À quoi sert l'expression régulière/^ \ s * $/do?
- 17. Dans Active Directory, à quoi sert mailNickname?
- 18. À quoi sert "string [] args" dans la classe Main?
- 19. à quoi sert tokens.h quand je programme une lexer?
- 20. A quoi sert $ this-> User dans le UsersController de CakePHP?
- 21. A quoi sert shared_ptr de boost (shared_ptr <Y> const & r, T * p)?
- 22. À quoi sert le dernier élément d'une liste dans Scheme?
- 23. à quoi sert le sel jeton anti-falsification?
- 24. À quoi sert ModelState.IsValid dans ASP.NET MVC dans NerdDinner?
- 25. Officiellement, à quoi sert le nom de fichier?
- 26. À quoi sert la collection TempData dans asp.net MVC?
- 27. À quoi sert le développement piloté par les modèles?
- 28. À quoi sert le paramètre de chemin HHOJSID URI?
- 29. À quoi sert la directive du compilateur @package dans Cocoa?
- 30. ASP.NET MVC, À quoi sert le dossier Modèles?
Attention - "int ** var" n'est pas une référence à un pointeur mais un pointeur vers un pointeur. – Konrad
@aku: Je pense que votre code est incorrect. La ligne devrait être int ** array = new int * [2]; – Destructor