Autore Topic: [C++] Inserimento non ordinato in container STL  (Letto 3735 volte)

Offline TheKaneB

  • Human Debugger
  • *****
  • Post: 5292
  • Karma: +20/-23
    • Mostra profilo
    • http://www.antoniobarba.org
Re: [C++] Inserimento non ordinato in container STL
« Risposta #15 il: 16 Novembre 2011, 09:10:57 »
un Iteratore non è altro che un tipo, in cui bisogna implementare l'operatore di dereferenziazione *, e gli operatori di incremento e decremento ++ e -- (non per forza entrambi, se la tua struttura dati è problematica puoi differenziare in forward iterator e reverse iterator). Il contenitore, poi, restituirà due iteratori, rispettivamente begin() e end(), che serviranno per puntare alla testa e alla coda della tua struttura dati. Per essere precisi dovrà restituire 4 iteratori, begin() normale, begin() const, end() normale, end() const. Le varianti "const" ritorneranno un const_iterator, che è uguale all'iteratore normale eccetto che i suoi metodi sono tutti const, cioè danno errore di compilazione se tenti di usarli per modficare il contenuto del container. Tra un po' spiegherò il perchè.

Se l'iteratore è una classe, puoi usare l'operator overloading per implementare queste funzioni. Ma può capitare che l'iteratore sia un tipo di base.

Ad esempio in un Vector<T> (che sostanzialmente incapsula un array ad allocazione dinamica), l'iteratore può essere semplicemente un puntatore come T*.

Infatti internamente troviamo l'array vero e proprio T* m_Data e gli operatori * ++ e -- sono già forniti dal linguaggio (aritmetica dei puntatori).

Nel caso di una lista concatenata, invece, l'operatore * può essere implementato con un banale return this->m_element->value mentre il ++ potrebbe essere un banale this->m_element = this->m_element->next; return this->m_element;.

Nella tua struttura, in particolare, potresti replicare esattamente l'implementazione dell'iteratore delle liste concatenate, perchè l'oggetto da scorrere è la lista chiamata History.

Questo articolo spiega come fare un iteratore usando i template della libreria Boost http://accu.org/index.php/journals/1527
Qui ulteriori esempi:
http://msdn.microsoft.com/en-us/magazine/cc301955.aspx
http://accu.org/index.php/journals/389 <-- questo qui sembra un buon articolo, abbastanza dettagliato

Un'altra cosa che ti consiglio di approfondire, è l'uso massiccio dei metodi const quando possibile. Questo ti da 2 vantaggi: permette al compilatore di ottimizzare meglio (compare @dsar ti spiegherà il perchè meglio di quanto saprei fare io :lol: ), e ti consente di individuare a compile time eventuali bug subdoli. Ad esempio se tenti di modificare l'istanza di un oggetto ottenuto tramite getter, faresti meglio ad esplicitare la richiesta usando un setter. Impostando tutti i getter a const (e soprattutto che ritornino dei const reference ad oggetti invece di oggetti by-value, a meno che non siano tipi primitivi), scarichi sul compilatore l'onere di scovare sovrascritture involontarie sugli oggetti ottenuti.

Questo crea qualche grattacapo all'inizio, ma su grandi progetti aiuta enormemente a scrivere codice robusto e il più possibile facile da debuggare.
« Ultima modifica: 01 Gennaio 1970, 02:00:00 da Guest »

Tags: