2009-09-11 4 views
4

J'ai vu cela dans notre code quelques fois et cela me rend immédiatement suspect. Mais puisque je ne connais pas l'intention originale, j'hésite à l'enlever.Quel serait le but de l'utilisation immédiate des opérateurs de référence et de déréférencement dans la séquence "& * B"?

//requires double indirection which I won't go into 
FooClass::FooFunction(void ** param) 
{ 
    //do something 
} 

SomeClass * A = new SomeClass(); 
SomeClass **B = &A; 
FooFunction(reinterpret_cast<void**>(&*B)); // what is happening here? 

La partie "& * B" est la partie en question? N'hésitez pas à intégrer l'explication du casting de réinterprétation mais je suis assez familier avec les techniques de casting.

+3

Etes-vous sûr que "SomeClass ** A = new A();" ne contient pas un type? Ne devrait-il pas être "SomeClass * A = new A();"? – mmmmmmmm

+7

Le code que vous avez montré ne peut pas être celui que vous demandez, parce qu'il est faux ('SomeClass ** A = new A()' ne compilera pas) dans un endroit critique pour la réponse ("what is' A'? "). Vous aurez probablement besoin de résoudre ce problème afin d'obtenir des réponses significatives. – sbi

+1

Ce code est mal formé. Vous ne pouvez pas utiliser le nom de la classe en tant qu'identifiant pour la variable. –

Répondre

3

Je ne vois qu'une seule raison: B a surchargé operator*() retourner un X, mais celui qui a écrit le code avait besoin d'un . (Notez que dans votre code, X est A*.) Le cas typique est celui des pointeurs intelligents et des itérateurs.

Si ce qui précède n'est pas le cas, peut-être que le code a été écrit pour être assez générique pour gérer les pointeurs/itérateurs intelligents. Ou il utilisait des pointeurs intelligents et celui qui l'a changé n'a pas pris la peine de changer &* aussi? Avez-vous passé en revue son histoire pour voir quand cela a été introduit et à quoi ressemblait le code?

+0

@sbi, alors dans ce cas serait-il inutile d'utiliser reinterpret_cast (B)? Je ne suis pas au courant d'un opérateur surchargé * pour ce ptr particulier, donc il semble que nous obtenons un ptr temporaire pour quelque chose pour lequel nous avons déjà une double indirection? – BuckFilledPlatypus

+0

Si 'B' est bien un pointeur nu (de type' SomeClass ** ') comme indiqué dans votre question, c'est certainement inutile. (Mais ça ne fait pas mal non plus.) – sbi

+0

Ok, ça répond à la question alors. Si ce n'est pas un cas particulier, c'est en effet inutile comme je le soupçonne. – BuckFilledPlatypus

10

J'ai fait des choses similaires avec les itérateurs - déréférencer l'itérateur pour obtenir une référence, puis faire l'opérateur "&" pour obtenir un pointeur.

Je ne vois pas pourquoi cela ferait quoi que ce soit ici. Si le type à droite de "& *" est un type de pointeur, il ne fait rien.

2

Considérons l'exemple suivant;

class A { 
public: 
    int f() { return 55; } 
}; 

class B { 
public: 
    B(A* a) : a(a) {} 
    A*& operator*() { return a; } 

    A* a; 
}; 

int main() { 
    A* a = new A(); 
    B b = a; 

    // &* calls operator*, then gets address of A 
    void** x = reinterpret_cast<void**>(&*b); 
    cout << reinterpret_cast<A*>(*x)->f() << endl; // prints 55 

    void** x2 = reinterpret_cast<void**>(b);  // compile error 
} 

Votre dernière modification de la question conduit à:

A* a = new A(); 
A** b = &a; 

void** x = reinterpret_cast<void**>(&*b); // now this is equal to the following 
void** x2 = reinterpret_cast<void**>(b); // so using &* make no sense 
+0

Si le p n'est pas un pointeur droit, alors oui c'est logique (bien que je taperai & (* p) comme p.get()), mais cela ressemble à un pointeur droit dans la question. –

+0

Si 'A' est un pointeur droit ici, alors la question d'OP n'a aucun sens. –

+0

Kirill, est-ce que vous dites ici que * p obtient le pointeur sur 'b' et ensuite nous créons un nouveau pointeur en ajoutant plus d'indirection à travers l'opérateur & ici? Peut-être ai-je mal compris avec l'introduction de shared_ptr. – BuckFilledPlatypus

Questions connexes