PDA

View Full Version : [c++]overloading [][]


NA01
22-10-2006, 10:06
dato che non compare nella lista di operatori, come lo si può implementare?
vi spiego...
ho una matrice stile c di valori interi (una serie di matrici blosum per chi interessasse :D), volevo farci un wrapper per utilizzare in automatico alcune traduzioni e controlli.
per una questione di precompatibilità con il codice già scritto sarebbe carino utilizzare l'accesso tramite [][], ma non ho idea di come si possa implementare...

grazie per l'attenzione, ciao!

-fidel-
22-10-2006, 11:22
in C++ si può fare l'overload di []. Ad esempio:


class vector {
int v[SIZE];
public:
vector() { register x; for (x=0; x<10; x++) v[x] =xi; } //costruttore
int vector::operator[] (int x); } // overload []
}

int vector::operator[] (int x) { return a[x]; } // Primo overload
int &array::operator[] (int x) { return a[x]; } // Secondo overload
// NOTA: con il secondo overload si permette di usare l'operatore a sinistra di un'assgnazione.

// implementazione dell'overload...


Inoltre, se la classe è friend l'operatore [] non può più essere soggetto ad overload.
Non mi risulta che sia possibilie fare l'overload di [][], ma non ho mai provato. Puoi provarci tu, seguendo l'esempio del codice postato (non ho implementato l'overload dal momento che è banale...).

marco.r
22-10-2006, 16:07
dato che non compare nella lista di operatori, come lo si può implementare?
vi spiego...
ho una matrice stile c di valori interi (una serie di matrici blosum per chi interessasse :D), volevo farci un wrapper per utilizzare in automatico alcune traduzioni e controlli.
per una questione di precompatibilità con il codice già scritto sarebbe carino utilizzare l'accesso tramite [][], ma non ho idea di come si possa implementare...

grazie per l'attenzione, ciao!
l'operatore [][] non esiste,devi simularlo tramite due chiamate a operator[] con un oggetto intermedio
qualcosa di simile al seguente:

/* ATTENZIONE: Il mio c++ e' un bel po' arrugginito... :D */
class Row
{
typedef value_type int;
typedef size_type int;
Matrix& matrix;
const size_type& row;

public:
Row( Matrix& m, const size_type& r):matrix(m),row(r){}

value_type& operator[](const size_type& col)
{ return matrix.data[row][col]; }
/* ... */
};

class Matrix
{
typedef value_type int;
typedef size_type int;
int rows,cols;
value_type **data;

public:
Row operator[](const size_type& row)
{ return Row(*this,row); }
/* .. */
};

in questo modo il primo [] ti crea un oggetto "riga" temporaneo su cui poi chiamare il secondo [].
E' possibile che tu perda un po' di efficenza; in linea teorica tutto questo catafalco sarebbe ottimizzabile in un bel "return self.data[row][col]", bisogna vedere se all'atto pratica il compilatore ci riesce :mbe:.
In alternativa prendi in considerazione di passare ad un operator ()(size_type,size_type), molto piu' semplice (soprattutto per il compilatore).
Edit: va da se' che la classe Row deve essere friend di Matrix