2009-07-27 23 views
10

Ho seguente classe: -overloading degli operatori in C++ come int + obj

class myclass 
{ 
    size_t st; 

    myclass(size_t pst) 
    { 
     st=pst; 
    } 

    operator int() 
    { 
     return (int)st; 
    } 

    int operator+(int intojb) 
    { 
     return int(st) + intobj; 
    } 

}; 

questo funziona bene finché io lo uso in questo modo: -

char* src="This is test string"; 
int i= myclass(strlen(src)) + 100; 

ma non sono in grado di fare questo: -

int i= 100+ myclass(strlen(src)); 

Qualche idea, come posso ottenere questo ??

risposta

19

Implementare l'esterno l'overloading degli operatori della classe:

class Num 
{ 
public: 
    Num(int i) 
    { 
     this->i = i; 
    } 

    int i; 
}; 

int operator+(int i, const Num& n) 
{ 
    return i + n.i; 
} 
+1

+1. Dovresti preferire comunque le versioni non associate, anche nei casi in cui non è necessario. Utilizza le varianti dei membri solo quando necessario. – jalf

+1

Preferisco sempre fare amicizia con i miei operatori non membri. –

2

Hai bisogno di un operatore di funzione globale + (int, MyClass) per fare questo:

int operator+(int intobj, myclass myobj) 
{ return intobj + int(myobj); } 
+1

Con la ricerca dipendente dall'argomento, non dovrebbe essere globale. –

11

È necessario implementare l'operatore come un non membro funzione per consentire una primitiva int sul lato sinistro.

int operator+(int lhs, const myclass& rhs) { 
    return lhs + (int)rhs; 
} 
3

Le altre risposte qui risolveranno il problema, ma il seguente è il modello che uso quando sto facendo questo:

class Num 
{ 
public: 
    Num(int i)  // Not explicit, allows implicit conversion to Num 
    : i_ (i) 
    { 
    } 

    Num (Num const & rhs) 
    : i_ (rhs.i_) 
    { 
    } 

    Num & operator+= (Num const & rhs) // Implement += 
    { 
    i_ += rhs.i_; 
    return *this; 
    } 

private: 
    int i_; 
}; 

// 
// Because of Num(int), any number on the LHS or RHS will implicitly 
// convert to Num - so no need to have lots of overloads 
Num operator+(Num const & lhs, Num const & rhs) 
{ 
    // 
    // Implement '+' using '+=' 
    Num tmp (lhs); 
    tmp+=rhs; 
    return tmp; 
} 

Uno dei principali vantaggi di questo approccio è che le funzioni può essere implementato in termini l'uno dall'altro riducendo la quantità di codice generale di cui hai bisogno.

UPDATE:

Per mantenere problemi di prestazioni a bada, probabilmente definire il non all'operatore membro + come una funzione inline qualcosa di simile:

inline Num operator+(Num lhs, Num const & rhs) 
{ 
    lhs+=rhs; 
    return lhs; 
} 

Le operazioni membri sono anche in linea (come viene dichiarato nell'organismo della classe) e quindi in tutto il codice dovrebbe essere molto vicino al costo dell'aggiunta di due oggetti grezzi int.

Infine, come sottolineato da jalf, le conseguenze di consentire conversioni implicite in generale devono essere considerate. L'esempio precedente presuppone che sia ragionevole convertire da un tipo integrale a un 'Num'.

+0

Ma non è garantito che la conversione da int sia un'operazione significativa. E la conversazione implicita può essere inefficiente rispetto alla semplice definizione di 'operator + (int, Num)' – jalf

+0

@jalf: Caveat per la conversione aggiunta. Per quanto riguarda la conversione implicita, se le funzioni sono in linea, un buon compilatore dovrebbe produrre un codice identico per quanto sopra come per il caso (int, Num). –