130 votes

Surcharge d'opérateur: fonction membre vs fonction non membre?

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?

162voto

Nawaz Points 148870

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

21voto

Charles Salvia Points 28661

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.

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