2011-01-12 14 views
9

Utilizzo l'ereditarietà privata in un progetto, nel senso "implementato in termini di". La classe base definisce operator [], e questa è la funzionalità che voglio usare. Così, hoereditarietà privata tramite direttiva, sovraccarichi?

class A : private B { 
    using B::operator[]; 
    // ... 
}; 

Tuttavia, come posso controllare quale versione dell'operatore [] ottengo? In realtà, ho bisogno di più di una, entrambe le versioni const e non const. Questo può essere realizzato?

+3

In questo caso è possibile utilizzare la composizione per fornire il risultato desiderato anziché l'ereditarietà privata. – James

+1

Sì, lo so ... l'ho cambiato in ereditarietà privata invece di ridurre la quantità di codice di inoltro. Quindi non è possibile? Come viene scelta la funzione in modo casuale? – carlpett

+0

Il codice sarà molto più facile da scrivere e mantenere se si utilizza la composizione anziché l'ereditarietà privata qui. La regola generale è quella di non utilizzare le funzionalità off-the-wall del C++ quando non sono assolutamente necessarie (da quello che hai detto finora, l'ereditarietà privata non è necessaria in questo caso). –

risposta

6

La mia comprensione è che il tuo using dovrebbe portare automaticamente tutti i diversi sovraccarichi dell'operatore. Ci sono alcuni sovraccarichi che si desidera escludere dall'essere portati nella classe figlio? In tal caso potrebbe essere meglio suddividere il lavoro in diverse funzioni con nomi diversi nel genitore e solo in using quelle che ti servono.

+0

Lo avrei pensato anch'io, ma ottengo errori di compilazione da scarto costante, nonostante ci siano versioni che restituiscono sia 'T &' che 'const T &' (modello typename T) – carlpett

+0

Quindi, questo è uno di loro "si aggiusta magicamente "volte ... Dopo aver osservato il codice e averlo ricompilato, improvvisamente funziona, e non posso per la vita di me capire cosa ho cambiato. Ciò che è cambiato però è che ho imparato un po 'di più sull'eredità, quindi grazie! – carlpett

2

Questo fa come previsto:

class A 
{ 
public: 
    int operator[](int idx) { return 0; } 
    int operator[](int idx) const { return 1; } 
}; 

class B : public A 
{ 
public: 
    using A::operator[]; 

    void opa() { cout << operator[](1) << endl; } 
    void opb() const { cout << operator[](1) << endl; } 
}; 

int main(void) 
{ 
    B b; 
    b.opa(); 
    b.opb(); 

    const B d = B(); 
    cout << d[1] << endl; // should trigger the const version of operator[] 
    return 0; 
} 

In altre parole, le versioni const appropriato const/non vengono iniettate B. NOTA: Se la versione const non viene fornita, si riceverà un errore del compilatore (funziona se l'ereditarietà è privata o pubblica).

+0

Grazie, buon esempio! – carlpett

+0

Aggiungerei anche 'b [2];' o simile a 'main' per mostrare che le funzioni dell'operatore possono essere utilizzate direttamente dall'esterno' classe B'. – aschepler

+0

@aschepler, buon punto, aggiornerà ... – Nim