2011-10-02 23 views
6

De manera concisa, mi objetivo es tener foo [bar] return type1, y foo [bar] = return type2.Sobrecarga de múltiples operadores

Estoy escribiendo un objeto en C++, y está viniendo bastante bien, sin embargo, hay solo una pequeña cosa que deseo hacer, pero parece imposible.

Mi objeto es una clase de almacenamiento, por lo que estoy usando un subíndice de matriz para acceder a los valores. También necesito asignar, así que también sobrecargo el operador =. Sin embargo, es un poco inconveniente porque los valores que mi clase contiene son objetos de primera clase, así que para mi sobrecarga de subíndices de matriz no puedo devolverlos como están. Tengo que devolver una clase intermedia para manejar el operador =, pero también quiero recuperar el valor sin tipeo adicional.

¿Hay alguna manera de hacer esto? Las formas atroces son aceptables.

Edición: He aquí un ejemplo de lo que (debe) hacer

#include<cstdio> 
#include<cstdlib> 

class foo{ 
    char* a[100]; 
    foo(){ 
     for(int i = 0; i < 100; i ++) 
      a[i] = 0; 
    } 
    char* operator[] (int location){ 
     return a[location]; 
    } 
    foo& operator[]= (int location, const char* value){ 
     if(a[location] == 0) 
      a[location] = (char*) malloc(strlen(value) + 1); 
     else 
      a[location] = (char*) realloc(a[location], strlen(value) + 1); 
     strcpy(a[location], value); 
    } 
}; 
int main(){ 
    foo bar; 
    bar[20] = "Hello"; 
    printf("bar[20] = %s\n", bar[20]); 
    bar[20] = "Hello There"; 
    printf("bar[20] = %s\n", bar[20]); 
    printf("bar[20][0] = %c\n", bar[20][0]); 
} 

Output: 
bar[20] = Hello 
bar[20] = Hello There 
bar[20][0] = H 

de nuevo Edit: Creo que voy a probar esto en un fraseo diferente, pero forma viable. ¿Hay alguna manera de sobrecargar el tipo de devolución cuando se hace referencia a una clase? Tal que si tengo

class foo{ 
    bool a; 
    bool operator /*referenced*/(){ 
     return a 
    } 
    foo& operator=(bool b){ 
     a = b; 
    } 
}; 
int main(){ 
    foo a; 
    a = b; 
    if(a == b) 
     printf("It Works!"); 
} 

que realmente funcionaría?

+0

podría darle un poco de código que muestra lo que está tratando ¿que hacer? –

+0

Hay un ejemplo – Kaslai

Respuesta

5

No hay operator[]=, por lo que la solución es escribir algún tipo de clase de contenedor con dos características principales: una operator= que toma un valor y lo fija al contenedor principal, y un operador de conversión implícita que toma el valor de la contenedor principal y lo devuelve. Su operator[] devolverá dicha envoltura.

class foo 
{ 
    friend class wrapper; 
public: 
    class wrapper 
    { 
     friend class foo; 
     foo & _parent; 
     int _index; 

     wrapper(foo & parent, int index) : _index(index), _parent(parent) {} 
    public: 
     wrapper & operator=(const char * value) 
     { 
      if(_parent.a[_index] == 0) 
       _parent.a[_index] = (char*) malloc(strlen(value) + 1); 
      else 
       _parent.a[_index] = (char*) realloc(_parent.a[_index], strlen(value) + 1); 
      strcpy(_parent.a[_index], value); 

      return *this; 
     } 

     operator char *() 
     { 
      return _parent.a[_index]; 
     } 
    }; 

    char* a[100]; 
    foo() 
    { 
     for(int i = 0; i < 100; i ++) 
      a[i] = 0; 
    } 
    wrapper operator[] (int location){ 
     return wrapper(*this, location); 
    } 
}; 

Para la segunda pregunta, bueno, siempre se puede sobrecargar operator== en foo. Pero tal vez no entendí bien.

+0

De acuerdo, ese es el sistema que había configurado, pero me molesta tener que escribir de forma adicional. C++ es mucho más abstracto que C, pero creo que no es tan abstracto como podría serlo. Oh, bueno, gracias por la contribución de tus muchachos. (Hubo otra respuesta, pero eliminó su publicación) – Kaslai

+0

@Aslai: Supuse que querías escribir extra * donde lo usas *. Cuando desee crear clases "fáciles de usar" en C++, a menudo significa * escribir * algunas cosas realmente feas. –

+0

Me refiero exactamente a * donde lo usa. * Tiene que hacer un operador adicional para obtener el valor, como un yeso o (de) referencia. – Kaslai

0

Si usted está dispuesto a utilizar C++ (como sugiere su etiqueta), entonces la mayor parte del trabajo se ha hecho para usted:

class foo: public vector<string> 
{ 
public: 
    foo() 
    { 
    resize(100); 
    } 
}; 

int main() 
{ 
    foo bar; 

    bar[20] = "Hello"; 
    cout << "bar[20] = " << bar[20] << endl; 
    bar[20] = "Hello There"; 
    cout << "bar[20] = " << bar[20] << endl; 
    cout << "bar[20][0] = " << bar[20][0] << endl; 
} 
Cuestiones relacionadas