2010-11-12 18 views
10

d1 + 4 funziona ma 4 + d1 non è possibile convertire 4 in modo implicito in un GMan. Perché non sono equivalenti?Nessuna conversione implicita nell'operatore sovraccarico

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; 
} 
+4

Hai provato a chiedere [GMan] (http://stackoverflow.com/users/87234/gman)? – sbi

+0

sbi No, non l'ho ancora. –

+5

@ Fan di GMan? Stupefacente. Dove sono i miei fan (se ce ne sono)? ': P' –

risposta

12

Una chiamata x + y è tradotto dal compilatore C++ in uno dei seguenti due chiamate (a seconda che x è di tipo classe, e se esista una funzione):

  1. funzione membro

    x.operator +(y); 
    
  2. funzione libero

    operator +(x, y); 
    

Ora C++ ha una regola semplice: nessuna conversione implicita può accadere prima che un operatore di accesso utente (.). In questo modo, x nel codice precedente non può subire una conversione implicita nel primo codice, ma può nel secondo.

Questa regola ha senso: se x potrebbe essere convertito implicitamente nel primo codice di cui sopra, il compilatore C++ non saprebbe più quale funzione chiamare (cioè quale classe appartiene a) in modo che avrebbe dovuto cercare tutto classi esistenti per una funzione membro corrispondente. Ciò potrebbe rovinare il sistema di tipo C++ e rendere le regole di sovraccarico ancora più complesse e confuse.

3

This risposta è corretta. Tali punti implicano quindi il modo canonico di implementare tali operatori:

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; 
} 

E così via per altri operatori.

Problemi correlati