J'ai lu qu'un opérateur surchargé déclaré en tant que membre de la fonction est asymétrique, car il ne peut avoir qu'un seul paramètre et l'autre paramètre passé est automatiquement le pointeur 'this'. Si aucune norme n'existe pour les comparer. D'autre part, de la surcharge de l'opérateur déclaré comme un ami est symétrique parce que nous passons deux arguments du même type, et par conséquent, ils peuvent être comparés. Ma question est que quand je peux toujours comparer un pointeur de lvalue à une référence, pourquoi sont des amis préféré? (l'utilisation d'une version asymétrique donne les mêmes résultats que symétrique) Pourquoi ne STL algorithmes utilisent uniquement symétrique versions?
Réponses
Trop de publicités?Si vous définissez votre opérateur surchargé la fonction en tant que membre de la fonction, le compilateur se traduit par des expressions comme s1 + s2
en s1.operator+(s2)
. Cela signifie que l'opérateur surchargé fonction membre appelée sur le premier opérande. C'est la façon dont les fonctions de membres de travailler!
Mais si le premier opérande est pas une classe? Il y a un problème majeur si nous voulons la surcharge d'un opérateur où le premier opérande n'est pas un type de classe, plutôt dire double
. Vous ne pouvez donc pas écrire comme cela 10.0 + s2
. Toutefois, vous pouvez écrire opérateur surchargé fonction de membre pour des expressions comme s1 + 10.0
.
Pour résoudre cette commande de problème, nous définissons l'opérateur surchargé la fonction en tant que friend
SI elle a besoin d'accéder private
des membres. Font friend
SEULEMENT quand il en a besoin pour accéder aux membres privés. Sinon tout simplement de le rendre non-ami non membre de la fonction pour améliorer l'encapsulation!
class Sample
{
public:
Sample operator + (const Sample& op2); //works with s1 + s2
Sample operator + (double op2); //works with s1 + 10.0
//Make it `friend` only when it needs to access private members.
//Otherwise simply make it **non-friend non-member** function.
friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2
}
La lecture de ces :
Un léger problème de commande d'opérandes
La Façon Dont Les Fonctions De Membre Améliorer L'Encapsulation
Ce n'est pas nécessairement une distinction entre friend
la surcharge de l'opérateur et de la fonction de membre de la surcharge de l'opérateur car il est entre mondial de la surcharge de l'opérateur et de la fonction de membre de la surcharge de l'opérateur.
Une raison de préférer un mondial de l'opérateur de surcharge est, si vous voulez permettre à des expressions où le type de classe apparaît sur la droite côté d'un opérateur binaire. Par exemple:
Foo f = 100;
int x = 10;
cout << x + f;
Cela ne fonctionne que s'il est un opérateur global de surcharge pour
Foo operator + (int x, const Foo& f);
Notez que l'opérateur global de surcharge n'a pas nécessairement besoin d'être un friend
fonction. Ceci n'est nécessaire que si elle a besoin d'accéder aux membres privés de Foo
, mais ce n'est pas toujours le cas.
Peu importe, si Foo
seulement avaient un membre de la fonction d'opérateur de surcharge, comme:
class Foo
{
...
Foo operator + (int x);
...
};
...alors nous ne serait en mesure d'avoir des expressions où un Foo
instance s'affiche sur la gauche de l'opérateur plus.