2010-03-28 25 views
8

Vorrei sovraccaricare operator[][] dare accesso interno ad una matrice 2D di char in C++.operatore [] [] C++

In questo momento sto solo sovraccarico operator[], che va qualcosa come

class Object 
{ 
    char ** charMap ; 
    char* operator[](int row) 
    { 
     return charMap[row] ; 
    } 
} ; 

Funziona ok .. E 'possibile ignorare operator[][] però?

+8

Non c'è operatore [] [] in C++. –

+1

Sovraccarico della matrice restituita dal sovraccarico [] OH SHI- –

risposta

18

Non cercare di farlo - come altri hanno detto, sovraccaricare operator [] il modo di fare in realtà fornisce la sintassi [][] gratuitamente. Ma non è una buona cosa.

Al contrario - distrugge l'incapsulamento e l'occultamento delle informazioni della classe girando un dettaglio di implementazione - il puntatore char* - all'esterno. In generale, questo non è consigliabile.

Un metodo migliore sarebbe implementare uno operator [,] che richiede più di un argomento o addirittura uno operator [][]. Ma nessuno dei due esiste in C++.

Così il solito modo di fare questo è di abbandonare operator [] del tutto per più di una dimensione. L'alternativa è quella di utilizzare pulito operator() invece perché tale operatore può avere più di un argomento:

class Object 
{ 
    char ** charMap ; 
    char& operator()(int row, int column) 
    { 
     return charMap[row][column]; 
    } 
}; 

Per ulteriori informazioni, vedere l'articolo del C++ FAQ Lite.

+2

+1 per suggerire 'operator()' – missingfaktor

+2

La tua risposta solleva dei buoni punti, ma l'operatore di supporto [] non ha bisogno di distruggere l'incapsulamento - invece di restituire un puntatore, puoi restituire un oggetto proxy che supporta operatore [] senza esponendo qualsiasi interno. –

+0

@Jerry: true ma l'oggetto proxy è molto più lavoro e qualsiasi vantaggio è dubbio per un oggetto multidimensionale (ovviamente, per un array * frastagliato * ha perfettamente senso). –

5

Non c'è operator[][]. La valutazione di a[x][y] prima chiama operator[] su a e quindi di nuovo operator[] sul risultato.

Quindi il operator[] dell'oggetto deve restituire un altro oggetto con il proprio operator[], che quindi accederà al valore richiesto.

2

Per quanto ne so non c'è alcuna cosa come operator[][]. Quello che puoi fare è che potresti restituire dal tuo metodo operator[] qualcosa che ha sovraccaricato lo operator[].

Attualmente lo stai facendo ora, perché restituisci char* che può essere indicizzato nuovamente con [].

17

Non v'è nessun operatore [][]: questo è due [] operazioni in fila. Si potrebbe:

  • Avere Object::operator[] restituire un oggetto di una seconda classe che rappresenta una fila, che ha il proprio operator[] metodo che accetta un numero di colonna;
  • Scrivete un metodo get(int row, int column) e l'uso che, invece di overloading degli operatori. Lo raccomanderei a meno che il tuo oggetto non debba assolutamente comportarsi come un array.
+4

+1 Se la classe non è destinata a comportarsi come una funzione, lasciare l'operatore() da solo. –

0

Non c'è [][] operatore. Quello che succede in realtà è che il secondo [] funziona sulla variabile restituita dal primo [].Poiché esiste già questa funzionalità, creerebbe ambiguità se esistesse un operatore [][].


Per esempio: supponiamo di avere una variabile x di qualche tipo T.

T x = new T(); 

Se usiamo l'operatore [], diciamo una variabile di un altro tipo Q viene restituito:

Q y = x[0]; 

e quindi utilizzando l'operatore [] su una variabile di tipo Q potrebbe restituire una variabile di tipo R:

R z = y[0]; 

Pertanto x[][] restituisce una variabile di t ipo R.

Diciamo che siamo in realtà stati in grado di sovraccaricare [][] per il tipo T tale che ha restituito un tipo S:

S a = x[0][0]; 

Il compilatore non avrebbe alcun modo di sapere se si deve utilizzare l'operatore [][] su x per restituire una variabile di tipo S oppure utilizzare l'operatore [] due volte di seguito per restituire una variabile di tipo R. Questa è l'ambiguità che ho menzionato sopra.


La cosa migliore se sei bloccato sull'utilizzo di parentesi quadre è quello di avere operator[] restituire una variabile che ha anche [] sovraccarico (o forse una variabile dello stesso tipo, con un set di bandiera), e hanno che inizialmente restituiva un accordo variabile con il secondo [].

Ma la soluzione migliore qui (come già menzionato in another answer) consiste nell'utilizzare un operatore diverso come ().

+0

L'ambiguità potrebbe essere facilmente risolta, ad es. usando un'analisi avida. Inoltre, il tuo primo codice contiene un errore poiché 'new' restituisce un * puntatore *. –