140 votes

Surcharge des opérateurs d’accès aux membres ->,. * (C ++)

Je comprends plus la surcharge d'opérateur, à l'exception de l'accès du membre opérateurs ->, .*, ->* etc.

En particulier, ce qui est passé à ces fonctions de l'exploitant, et ce qui doit être retourné?

Comment fonctionne la fonction opérateur (par exemple, operator->(...) ) savent ce membre est désigné? Peut-il le savoir? Est-il même besoin de savoir?

Enfin, il y a aucune const considérations qui doivent être prises en compte? Par exemple, en cas de surcharge quelque chose comme operator[], généralement vous aurez besoin d'un const et non const version. Faire de l'accès des membres des exploitants ont besoin const et non const versions?

159voto

Potatoswatter Points 70305

->

C'est la seule vraiment difficile. Il doit être une fonction membre non statique, et il ne prend pas d'arguments. La valeur de retour est utilisé pour effectuer la recherche d'un membre.

Si la valeur de retour est un autre objet de type classe, pas un pointeur, puis par la suite la recherche de membre est également géré par un operator-> fonction. Ceci est appelé le "drill-down comportement." La langue des chaînes d'ensemble de l' operator-> des appels jusqu'à ce que le dernier retourne un pointeur.

struct client
    { int a; };

struct proxy {
    client *target;
    client *operator->() const
        { return target; }
};

struct proxy2 {
    proxy *target;
    proxy &operator->() const
        { return * target; }
};

void f() {
    client x = { 3 };
    proxy y = { & x };
    proxy2 z = { & y };

    std::cout << x.a << y->a << z->a; // print "333"
}

->*

Celui-ci est seulement difficile par le fait qu'il n'y a rien de spécial à ce sujet. Le non surchargé version nécessite un objet de pointeur de type de classe sur la gauche et un objet de pointeur de type de membre sur la droite. Mais quand vous surcharger, vous pouvez prendre tous les arguments que vous aimez et de retour tout ce que vous voulez. Il n'a même pas à être un membre non statique.

En d'autres termes, celui-ci est un opérateur binaire comme +, -, et /. Voir aussi: Sont libre d'opérateur->* surcharges mal?

.* et .

On ne peut pas être surchargé. Il y a déjà un construit-dans le sens que quand la gauche est de type classe. Peut-être qu'il ferait un peu de sens pour être en mesure de les définir pour un pointeur sur le côté gauche, mais la conception de langage comité a décidé que ce serait plus à confusion qu'utile.

La surcharge ->, ->*, ., et .* pouvez remplir uniquement dans le cas où une expression serait pas défini, il ne peut changer le sens d'une expression qui serait valable sans surcharge.

51voto

Totonga Points 2162

L'opérateur -> est sepecial.

"Il a d'autres, atypique contraintes: Il doit retourner un objet (ou une référence à un objet) qui dispose également d'un déréférencement de pointeur de l'opérateur, ou il doit retourner un pointeur qui peut être utilisé pour sélectionner ce que l'opérateur de déréférencement de pointeur flèche." Bruce Eckel: la Pensée du RPC Vol-un : opérateur->

L'opérateur est faite vor commode de sorte que vous n'avez pas à appeler

a->->func();

mais

a->func();

Que fait l'opérateur-> différent de tous les autres opérateurs.

27voto

6502 Points 42700

Vous ne pouvez pas surcharger l'accès des membres . (c'est à dire la deuxième partie de ce qu' -> t). Cependant, vous pouvez surcharger la unaire de déférence opérateur * (c'est à dire la première partie de ce -> t).

Le C++ -> opérateur est fondamentalement l'union de deux étapes et ce qui est clair, si vous pensez qu' x->y est équivalent à (*x).y. C++ permet de personnaliser quoi faire avec l' (*x) part x est une instance de votre classe.

La sémantique pour -> la surcharge est un peu étrange parce que le C++ permet de retourner un pointeur normal (qu'il sera utilisé pour trouver l'objet pointé) ou de retourner une instance d'une autre classe si cette classe fournit également un -> de l'opérateur. Lorsque, dans ce second cas, la recherche de la déréférencé objet continue à partir de cette nouvelle instance.

10voto

John Chadwick Points 1903

L'opérateur -> ne sait pas sur quel membre est pointé, il fournit simplement un objet sur lequel effectuer l'accès réel au membre.

De plus, je ne vois aucune raison pour laquelle vous ne pouvez pas fournir de versions const et non const.

7voto

Asaf Points 2265

Lorsque vous surcharge de l'opérateur->() (pas d'arguments sont passés par ici), ce que le compilateur ne fait appelle -> de manière récursive jusqu'à ce qu'il retourne un réel pointeur vers un type. Il utilise ensuite le membre correct/méthode.

Ceci est utile, par exemple, pour créer un pointeur intelligent de la classe qui encapsule le pointeur. La surcharge de l'opérateur ->, est appelé, fait tout ce qu'il fait (p. ex. verrouillage pour la sécurité des threads), retourne le pointeur interne et ensuite, le compilateur appelle -> pour ce pointeur interne.

Comme pour constness - il été répondu dans les commentaires et les autres réponses (vous pouvez, et devez, fournir à la fois).

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