Frage

d1 + 4 funktioniert aber 4 + d1 nicht, obwohl 4 kann implizit in einen GMan umgewandelt werden. Warum sind sie nicht gleichwertig?

struct GMan
{
    int a, b;

    GMan() : a(), b() {}
    GMan(int _a) : a(_a), b() {}
    GMan(int _a, int _b) : a(_a), b(_b) {}

    GMan operator +(const GMan& _b)
    {
         GMan d;
         d.a = this->a + _b.a;
         d.b = this->b + _b.b;
         return d;
    }
};

int main()
{
    GMan d1(1, 2), d(2);
    GMan d3;
    d3 = d1 + 4; 
    d3 = 4 + d1;
}
War es hilfreich?

Lösung

Ein Anruf x + y durch die C ++ Compiler in eine der folgenden zwei Anrufe übersetzt wird (je nachdem, ob x ist der Klasse-Typ, und ob eine solche Funktion existiert):

  1. Member-Funktion

    x.operator +(y);
    
  2. Free Funktion

    operator +(x, y);
    

Jetzt C ++ hat eine einfache Regel: keine implizite Konvertierung vor einem Mitglied Zugang Betreiber passieren kann (.). Auf diese Weise x in dem obigen Code kann eine implizite Konvertierung in dem ersten Code nicht unterziehen, aber es kann in den zweiten.

Diese Regel macht Sinn: wenn x oben implizit in dem ersten Code umgewandelt werden könnte, die C ++ Compiler würde weiß nicht mehr, welche Funktion Anruf (dh welcher Klasse es gehört), so würde ich suchen hat alle vorhandenen Klassen für eine passende Elementfunktion. Das würde Chaos mit C ++‘Typ-System und macht die Überlastung Regeln noch komplizierter und verwirrend spielen.

Andere Tipps

Diese Antwort ist richtig. Diese Punkte dann ziehen die kanonische Weise solche Betreiber der Umsetzung:

struct GMan
{
    int a, b;

    /* Side-note: these could be combined:
    GMan():a(),b(){}
    GMan(int _a):a(_a),b(){}
    GMan(int _a, int _b):a(_a),b(_b){}
    */
    GMan(int _a = 0, int _b = 0) : a(_a), b(_b){} // into this

    // first implement the mutating operator
    GMan& operator+=(const GMan& _b)
    {
        // the use of 'this' to access members
        // is generally seen as noise
        a += _b.a;
        b += _b.b;

        return *this;
    }
};

// then use it to implement the non-mutating operator, as a free-function
// (always prefer free-functions over member-functions, for various reasons)
GMan operator+(GMan _a, const GMan& _b)
{
    _a += b; // code re-use
    return _a;
}

Und so weiter für andere Betreiber.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top