Surcharge de l'opérateur en dehors de la classe [dupliquer]

Cette question a déjà une réponse ici:

Il y a deux façons de surcharger les opérateurs pour une Classe C++:

Classe intérieure

class Vector2
{
public:
    float x, y ;

    Vector2 operator+( const Vector2 & other )
    {
        Vector2 ans ;
        ans.x = x + other.x ;
        ans.y = y + other.y ;
        return ans ;
    }
} ;

Hors classe

class Vector2
{
public:
    float x, y ;
} ;

Vector2 operator+( const Vector2& v1, const Vector2& v2 )
{
    Vector2 ans ;
    ans.x = v1.x + v2.x ;
    ans.y = v1.y + v2.y ;
    return ans ;
}

(apparemment en C# vous ne pouvez utiliser que la méthode "outside class".)

En C++, quel chemin est le plus correct? Ce qui est préférable?

36
demandé sur bobobobo 2010-03-11 17:51:30

3 réponses

La question de base est "voulez-vous que les conversions soient effectuées sur le paramètre de gauche d'un opérateur?". Si oui, utilisez une fonction Gratuite. Si non, utilisez un membre de la classe.

Par exemple, pour operator+() pour les chaînes, nous voulons que les conversions soient effectuées afin que nous puissions dire des choses comme:

string a = "bar";
string b = "foo" + a;

Où une conversion est effectuée à tourner la char * "foo" en std::string. Alors, nous faisons operator+() pour les chaînes dans une fonction libre.

45
répondu Azeem 2018-04-20 09:42:34

Premièrement: les deux façons différentes sont vraiment "surcharge en tant que membre" et "surcharge en tant que non-membre", et ce dernier a deux façons différentes de l'écrire (as-friend-inside class definition et outside class definition). Les appeler "à l'intérieur de la classe" et "en dehors de la classe" va vous confondre.


Surcharges pour +=, +, -=, -, etc. avoir un modèle spécial:

struct Vector2 {
  float x, y;
  Vector2& operator+=(Vector2 const& other) {
    x += other.x;
    y += other.y;
    return *this;
  }
  Vector2& operator-=(Vector2 const& other) {
    x -= other.x;
    y -= other.y;
    return *this;
  }
};
Vector2 operator+(Vector2 a, Vector2 const& b) {
  // note 'a' is passed by value and thus copied
  a += b;
  return a;
}
Vector2 operator-(Vector2 a, Vector2 const& b) { return a -= b; } // compact

Ce modèle permet les conversions mentionnées dans les autres réponses pour L'argument LHS tout en simplifiant le la mise en œuvre de façon considérable. (Membre ou non-membre permet des conversions pour le RHS lorsqu'il est passé soit en tant que const& ou en valeur, comme il se doit.) Bien sûr, cela ne s'applique que lorsque vous voulez réellement surcharger les deux + = et +, - = et -, etc. mais c'est encore courante.


De plus, vous souhaitez parfois déclarer votre op + non membre, etc. comme amis dans la définition de classe en utilisant le Barton-nackman trick , car en raison de bizarreries de modèles et en surcharge, il peut ne pas être trouvé sinon .

15
répondu 2010-05-16 22:23:08

Il y a une excellente discussion de ce problème dans le C++ efficace de Meyer: L'article 24 est "déclarer des fonctions non-membres lorsque les conversions de type doivent s'appliquer à tous les paramètres" et l'article 46 Est "définir des fonctions non-membres dans les modèles lorsque les conversions de type sont souhaitées".

4
répondu Francesco 2010-03-11 15:57:56