2009-07-27 18 views
10

He siguientes: -Sobrecarga de operadores en C++ como 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; 
    } 

}; 

esto funciona bien siempre y cuando lo uso como esto: -

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

pero soy incapaz de hacer esto: -

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

Cualquier idea, ¿cómo puedo lograr esto ??

Respuesta

19

Implementar el exterior sobrecarga de operadores de la clase:

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

    int i; 
}; 

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

+1. De todos modos, debería preferir las versiones que no sean miembros, incluso en los casos en que no sea necesario. Solo use las variantes de miembros cuando sea necesario. – jalf

+1

Siempre prefiero hacer amistad con mis operadores no miembros. –

2

Se necesita un operador de la función global + (int, miclase) para hacer esto:

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

Con búsqueda dependiente de argumento, no debería ser global. –

11

Hay que aplicar el operador como una función no miembro para permitir una primitiva int en el lado izquierdo.

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

Las otras respuestas aquí va a resolver el problema, pero el siguiente es el patrón que utilizo cuando estoy haciendo esto:

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

Una de las principales ventajas de este enfoque es que sus funciones puede implementarse en términos de reducción de la cantidad total de código que necesita.

ACTUALIZACIÓN:

Para evitar que los problemas de rendimiento en la bahía, probablemente definir el operador de miembro + no como una función en línea algo como:

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

Las operaciones miembros son también en línea (como lo se declara en el cuerpo de la clase) y, por lo tanto, en todo el código debería estar muy cerca del costo de agregar dos objetos int crudos.

Finalmente, como señala jalf, se deben tener en cuenta las consecuencias de permitir conversiones implícitas en general. El ejemplo anterior asume que es sensato convertir de un tipo integral a un 'Num'.

+0

Pero no hay garantía de que la conversión desde int sea una operación significativa. Y la conversación implícita puede ser ineficiente en comparación con simplemente definir 'operator + (int, Num)' – jalf

+0

@jalf: Advertencia para la conversión agregada. Con respecto a la conversión implícita, si las funciones están en línea, entonces un buen compilador debe producir un código idéntico para el anterior, como lo hace para el caso (int, Num). –