Il serait très utile de pouvoir surcharger le. en C++ et retourne une référence à un objet.
Vous pouvez surcharger operator->
et operator*
mais non operator.
Y a-t-il une raison technique à cela?
Voir cette citation de Bjarne Stroustrup :
Opérateur. (point) pourrait en principe être surchargé en utilisant la même technique que celle utilisée pour ->. Cependant, cela peut conduire à se demander si une opération est destinée à la surcharge d'objet. ou un objet visé par. Par exemple:
class Y { public: void f(); // ... }; class X { // assume that you can overload . Y* p; Y& operator.() { return *p; } void f(); // ... }; void g(X& x) { x.f(); // X::f or Y::f or error? }
Ce problème peut être résolu de plusieurs manières. Au moment de la normalisation, il n'était pas évident de savoir quelle voie serait la meilleure. Pour plus de détails, voir The Design and Evolution of C++ .
Stroustrup a déclaré que C++ devrait être un langage extensible, mais pas mutable.
L'opérateur point (accès aux attributs) a été considéré comme trop proche du cœur du langage pour permettre une surcharge.
Voir La conception et l'évolution de C++ , page 242, section 11.5.2 Références intelligentes .
Quand j'ai décidé d'autoriser la surcharge de l'opérateur
->
, Je me suis naturellement demandé si l'opérateur.
pourrait être surchargé de la même manière.À l'époque, je considérais les arguments suivants comme concluants: si
obj
est un objet de classe alorsobj.m
a une signification pour chaque membrem
de la classe de cet objet. Nous essayons de ne pas rendre le langage mutable en redéfinissant les opérations intégrées (bien que cette règle soit violée pour=
par grand besoin, et pour unaire&
).Si nous permettions une surcharge de
.
pour une classeX
, nous ne pourrions pas accéder aux membres deX
par des moyens normaux; il faudrait utiliser un pointeur et->
, mais->
et&
pourrait également avoir été redéfini. Je voulais un langage extensible, pas un langage mutable.Ces arguments sont importants, mais pas concluants. En particulier, en 1990, Jim Adcock a proposé d'autoriser la surcharge de l'opérateur
.
exactement la façon dont l'opérateur->
est.
Le "je" dans cette citation est Bjarne Stroustrup. Vous ne pouvez pas être plus autoritaire que cela.
Si vous voulez vraiment comprendre le C++ (comme dans "pourquoi est-ce ainsi"), vous devez absolument lire ce livre.
Stroustrup a une réponse à cette question :
Opérateur. (point) pourrait en principe être surchargé en utilisant la même technique que celle utilisée pour ->. Cependant, cela peut conduire à se demander si une opération est destinée à la surcharge d'objet. ou un objet visé par. Par exemple:
class Y { public: void f(); // ... }; class X { // assume that you can overload . Y* p; Y& operator.() { return *p; } void f(); // ... }; void g(X& x) { x.f(); // X::f or Y::f or error? }
Ce problème peut être résolu de plusieurs manières. Au moment de la normalisation, il n'était pas évident de savoir quelle voie serait la meilleure. Pour plus de détails, voir D&E .
Il est très facile à comprendre, si vous passez par le mécanisme interne d'invocation de fonction opérateur, disons qu'un complexe de classe peut avoir deux membres r pour la partie réelle et i pour la partie imaginaire. Disons Complexe C1 (10,20), C2 (10,2) // nous supposons qu'il existe déjà un constructeur à deux arguments dans la classe. Maintenant, si vous écrivez C1 + C2 comme une instruction, le compilateur essaie de trouver la version surchargée de l'opérateur + sur un nombre complexe. Maintenant, nous supposons que je surcharge l'opérateur +, donc C1 + C2 traduit en interne par c1.operator + (c2) Supposons maintenant pour le temps les êtres que vous pouvez surcharger '.' opérateur. alors pensez maintenant à l'appel suivant C1.disp () // affiche le contenu d'un objet complexe Essayez maintenant de le représenter comme une représentation interne C1.operator. (------), des choses complètement désordonnées créées. C'est la raison pour laquelle nous ne pouvons pas surcharger ''. opérateur