105 votes

Quand utiliser addressof(x) au lieu de &x ?

Comment décider si j'ai besoin addressof(x) au lieu de &x lors de la saisie de l'adresse d'un objet ?


Il semble que la question ait été confuse, une clarification s'impose donc :

addressof contourne manifestement l'opérateur surchargé "address-of". J'en suis déjà conscient.

Ce que je veux savoir, c'est.. :
Comment savoir si c'est ce que je veux vraiment faire ? (Surtout à l'intérieur d'un modèle, etc.)

Existe-t-il une sorte de "règle" qui m'aide à déterminer quand j'ai besoin de addressof au lieu de & ?
Après tout, ils renvoient tous deux l'"adresse" de l'objet, alors quand dois-je utiliser l'un ou l'autre ?

150voto

Nicol Bolas Points 133791

Vous utilisez std::addressof quand il le faut. Malheureusement, "quand il le faut" inclut chaque fois que vous travaillez dans un modèle de code et que vous voulez transformer une variable de type inconnu T o T& en un véritable pointeur sur la mémoire de cette variable.

Le comité C++ ayant stupidement autorisé la surcharge de l'opérateur de référence (à des fins peu légitimes), il est possible pour un utilisateur d'instancier votre modèle avec un type pour lequel vous ne pouvez pas utiliser l'opérateur de référence pour obtenir un pointeur réel. std::addressof est un moyen de contourner les utilisateurs qui se servent de cette caractéristique douteuse du C++ pour faire ce que le langage aurait dû garantir dès le départ.

En bref, il s'agit d'un correctif de bibliothèque pour une stupidité de langage. Utilisez-le dans le code des modèles au lieu de & si vous voulez vous assurer que les utilisateurs ne peuvent pas casser votre code. Si vous pouvez faire confiance à vos utilisateurs pour ne pas utiliser cette fonctionnalité mal conçue, vous pouvez alors utiliser & .

19voto

Luchian Grigore Points 136646

S'il s'agit d'un type défini par l'utilisateur avec une surcharge unaire operator& et que vous souhaitez obtenir son adresse, utilisez addressof .

Je dirais qu'il faut toujours utiliser & car, comme vous le dites, si vous ne le faites pas, cela va à l'encontre de l'objectif de la surcharge. Sauf si bien sûr, vous faites quelque chose de significatif avec la surcharge, auquel cas vous auriez besoin de addressof (à l'extérieur de la classe, à l'intérieur vous pouvez simplement utiliser this ), mais il faut être très sûr de ce que l'on fait.

En voici d'autres - si vous voulez vous surcharger operator& en dehors de la classe (vous pouvez), vous doivent utiliser addressof pour renvoyer l'adresse, sinon il en résulte une récursion infinie :

struct Class
{
   virtual ~Class() {}
   int x;
};

void* operator&(const Class& x)
{
    //return &x; <---- infinite recursion
    return addressof(x) + 4; //I know this isn't safe
                             //but I also know the intrinsics of my compiler
                             //and platform to know this will actually return
                             //the address to the first data member
}

Je sais que ce n'est pas sûr.

11voto

juanchopanza Points 115680

Utilisez-le lorsque vous souhaitez connaître l'adresse réelle de l'objet, et non pas le résultat d'un address-of operator& surcharge.

8voto

Benjamin Lindley Points 51005

Ce n'est que mon avis :

À moins de faire partie de l'équipe qui conçoit la classe et son interface, jamais. Personnellement, je n'ai jamais vu de bonne raison de surcharger cet opérateur. Mais si quelqu'un conçoit une classe où cela a du sens, et en supposant que la classe est destinée à une consommation publique (c'est-à-dire que la classe n'est pas réservée à un usage interne dans une bibliothèque particulière), je m'attends à ce que la classe fonctionne dans un code normal qui s'attend naturellement à ce que l'opérateur & signifie "adresse de". Si la classe qui surcharge l'opérateur n'est pas conçue de manière aussi raisonnable, alors je n'utiliserais pas cette classe, un point c'est tout. Parce que soit cette classe est cassée, soit elle n'est pas destinée à être utilisée en dehors de la bibliothèque dont elle fait partie.

7voto

Jonathan Wakely Points 45593

Après tout, ils renvoient tous deux l'"adresse" de l'objet, alors quand dois-je utiliser l'un ou l'autre ?

Vous n'avez absolument aucune garantie qu'un appareil surchargé operator& est l'"adresse" de l'objet, il y a de fortes chances qu'elle ne le soit pas, sinon l'auteur de la classe n'aurait probablement pas pris la peine de la surcharger. Il aurait pu la surcharger pour qu'elle renvoie un type différent, ou même pour qu'elle renvoie void s'ils tentent malencontreusement d'empêcher les gens de prendre son adresse.

Si vous voulez un pointeur sur un objet qui pourrait ont surchargé & (par exemple parce que son type est un paramètre de modèle et que vous ne le savez pas), utilisez alors soit std::addressof ou documenter que votre modèle ne supporte pas les types qui ne renvoient pas l'adresse réelle de l'objet comme le bon type.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X