2015-08-26 11 views
5

mio problema specifico è che ho un membro QMultiHash<Foo,Bar*>private, e mi piacerebbe per fornire l'accesso ai valori del hash, ma per const versioni delle voci, dichiarando:Converti (Qt) il contenitore di oggetti nel contenitore di oggetti const in modo efficiente?

QList<const Bar*> getBars(Foo f) const; 

Is c'è un modo più pulito/più efficiente di "consolare" gli articoli all'interno di di un contenitore Qt rispetto alla brutta/inefficiente creazione di un nuovo contenitore con elementi const e puntatori di copia dalla sorgente (QMultiHash<K,V>::values() in questo caso)?

Ho paura che la risposta potrebbe essere "no", ma volevo essere sicuro di non mancare qualche magia di sintassi Qt/C++ (03) per farlo.

+1

Vedere http://stackoverflow.com/questions/10265695/treat-vectorint-as-vectorconst-int-without-copying-c0x Non so una soluzione (tranne forse un enorme brutto attacco), ma è un 'for' loop un così grande affare?Semplicemente copiando i puntatori, dubito che questo influenzi le tue prestazioni - a meno che il 'QList' non sia enorme e tu abbia requisiti di prestazioni molto elevate. – Armaghast

+0

Inoltre, controllare http://stackoverflow.com/questions/2102244/vector-and-const per il motivo. – Armaghast

+0

In questo caso particolare, non è un grosso problema (e sono andato avanti e l'ho implementato in quel modo). Ma offende il mio senso dello stile, e in altri casi nella mia applicazione (visualizzazione dei dati interattiva), potrei aver bisogno di fare operazioni interattive sulla UI su contenitori di oggetti glifi di grafico ~ 1000-10000s in cui sto ispezionando ma non cambiando gli oggetti glifo senza ritardare l'interfaccia utente solo per ottenere un contenitore di puntatori const. – eclarkso

risposta

0

Ci sono due modi. Il modo ovvio che hai menzionato è di usare C++ 11 e convertirlo tu stesso a QList<const Bar*>.

QList<const Bar*> getList() const 
{ 
    QList<const Bar*> list; 

    for(Bar *b : m_List) //where m_List is your private memebr QList<Bar*> 
     list << b; 

    return list; 
} 

L'altro modo è quello di convertire il QList stesso per const QList<Bar*> che può essere fatto "magicamente" restituendo la lista da una funzione const per esempio:

const QList<Bar*> getList() const 
{ 
    return m_List; //where m_List is your private memebr QList<Bar*> 
} 

quale usare dipende dal vostro esigenze. Da ciò che descrivi hai bisogno di ispezionare gli elementi senza cambiarli. Sembra che in realtà non hai affatto bisogno dell'elenco modificabile. La prima variante sembra già un overkill. Si desidera const Bar* presumibilmente perché non si desidera che cambi per errore quando si ispeziona l'elemento. Per esaminare tutti gli elementi per esempio si potrebbe fare (aggiungendo const automaticamente per ogni elemento):

for(const Bar *b : myObject->getList()) 
    //do only const stuff with b 

Se non avete una buona ragione per la restituzione QList<const Bar*> come ad esempio che è necessario l'elenco di essere modificabili non vale la pena il guai e danno prestazioni. È possibile limitare Bar * con const quando si accede a se stessi utilizzando C++ 11 for in un modo descritto o utilizzando iteratori const. Da ciò che ho raccolto, consiglierei di usare quello piuttosto che convertire i valori della lista (possibilmente enorme) in const.

E un ultimo consiglio, se le liste sono davvero enorme ed è necessario ogni goccia di prestazione considerare:

const QList<Bar*> &getList() const 

La condivisione implicita di Qt fa nel precedente frammento di codice sul proprio credo, ma questo assicura che la lista non verrà mai copiata o modificata durante l'ispezione.

+0

Si noti che il mio membro effettivo è un QMultiHash, e quello a cui voglio fornire l'accesso const è l'elenco di valori da QMultiHash :: values ​​()., E come tale l'ultimo riferimento const non è un'opzione. Si noti inoltre che un motivo importante per fornire tale accesso è per la correttezza costante; inoltre, preferirei non fare affidamento sulle buone grazie di me stesso o di altri per accedere alla lista (tramite iteratori e costanti) in modo appropriato. – eclarkso

+0

@eclarkso In tal caso, l'unica opzione è quella di creare un elenco di questo tipo. Anche se esistesse una funzione che la creerebbe per te, farebbe praticamente la stessa cosa - creando una nuova lista con elementi const. Ad ogni modo, usa C++ 11 per farlo in quanto è il modo più veloce attualmente disponibile. A meno che non si verifichino problemi di prestazioni con l'ispezione che impiega troppo tempo perché la lista è troppo grande (e la conversione impiega troppo tempo) non ci dovrebbero essere problemi. Se le prestazioni diventano un problema, probabilmente dovrai riconsiderare le tue priorità o il tuo design. In bocca al lupo! – Resurrection

0

Nessun modo efficace per "consolare" oggetti nell'array esistente. Ma se memorizzi davvero una lista di puntatori. Può essere veloce per convertire non puntatori "const" in puntatori "const" in un ciclo semplice ?! (Ad esempio, crea una nuova lista) La seconda soluzione è rendere gli oggetti "const" nell'elenco inizialmente, quando si compila quell'elenco. E il terzo modo è rendere i propri figli classe del tuo elenco cosa può restituire solo "const" di riferimento o iteratore per gli elementi memorizzati.

+0

Spero che tu mi capisca senza esempi di codice. Per favore fatemi sapere se no. Spiegherò di più. – stanislav888

Problemi correlati