2009-08-13 12 views
15

Noto la discussione della domanda simile: Limit size of Queue<T> in .NET? Questo è esattamente ciò che voglio fare, ma non sto usando .net ma GNU C++. Non ho riferimenti alla classe base in GNU C++, quindi java come super.***() o .net come base.***() non funzionerà. Ho cercato di ereditare dalla classe di coda ma risulta invano.dimensione limite della coda <T> in C++

Che cosa voglio fare: specificare la dimensione della coda e automaticamente deselezionare quando la coda è piena. Per essere precisi: se la dimensione massima della mia coda è 2, quando spingo il terzo elemento, il primo elemento verrà automaticamente estratto prima di premere il nuovo elemento.

Come implementare tale coda?

Grazie.

+1

È necessario per spiegare cosa intendi con "rimozione automatica": vuoi dire scartare le cose in testa alla coda? –

+0

@Neil: stavo per fare la stessa domanda, ma poi ho prima fatto clic sul post collegato. ':)' – sbi

risposta

10

Crea una nuova classe che incapsula la coda e applica un limite di dimensioni nella nuova classe.

+1

vuoi dire: creare una nuova classe con una coda variabile membro? – Lily

+0

+1 Questo mi sembra la soluzione più semplice. – DeusAduro

+0

@Lily, credo che sia quello a cui sta andando. Questo è abbastanza semplice semplicemente perché una coda ha solo due importanti mutatori, push_back, pop_front. E nel tuo caso, se si disconnette automaticamente, potresti avere solo bisogno di push_back come membro pubblico. – DeusAduro

0

Supponendo che per Queue<T> si intende std::queue<T>: Una coda è solo un adattatore per alcuni container sottostanti che viene passato in fase di compilazione. Potresti usare un contenitore che fa già ciò che vuoi. La soluzione migliore sembra essere un buffer circolare, se ne trovi uno che supporta le operazioni necessarie per std::queue (penso che sia push_back(), pop_front() e size(), ma non ho controllato).

7

Sembra boost::circuclar_buffer fa quello che stai cercando:

Scrivendo ad un Buffer Full

Ci sono diverse opzioni come affrontare con il caso in cui una fonte di dati produce più dati di quelli che possono essere inseriti nel buffer di dimensioni fisse :

  1. Informare i dati in modo per aspettare fino al c'è spazio nel buffer (ad es. per lanciare un'eccezione di overflow).
  2. Se i dati più vecchi sono i più importanti da , ignorare i nuovi dati dall'origine fino a quando non c'è spazio nel buffer .
  3. Se i dati più recenti sono i più importanti, scrivere sui dati più vecchi .
  4. Lascia che il produttore sia responsabile della verifica della dimensione di del buffer prima di scriverlo.

È evidente che il circular_buffer attua la terza opzione . Ma potrebbe essere meno evidente che non implementa alcuna altra opzione - in particolare i primi due. Uno può ottenere un'impressione che il circular_buffer dovrebbe implementare prime tre opzioni e offrire un meccanismo di scegliere tra di loro. Questa impressione è errata. circular_buffer è stato progettato e ottimizzato per essere circolare (il che significa che sovrascrive i dati più vecchi quando pieno).Se tale meccanismo di controllo fosse stato abilitato, sarebbe solo complicare le cose e l'utilizzo di dello circular_buffer sarebbe probabilmente meno semplice.

15

So che hai detto "automatico", ma, per mantenere le cose semplici: Incapsulare solo l'ing Enqueue() in una funzione locale (no, non OO pulita, ma funziona):

Queue<T> myQueue = new Queue<T>(); 

void addToMyQueue(T param) 
{ 
    myQueue.Enqueue(param); //or push(param) 
    if (myQueue.Count > LIMIT) 
     myQueue.Dequeue(); //or pop() 
} 

void main() 
{ 
    addToMyQueue(param); 
} 
+1

È una coda standard e soddisfa lo scopo (cioè dimensione fissa della coda). Dico che questa è la soluzione più pulita. – wmac

+0

A proposito, è più probabile che sia il formato di Java. La classe è la coda e l'inizializzazione non ha bisogno di una nuova coda, solo myQueue; sarà sufficiente e sarà necessario utilizzare push, pop e size al posto di questi metodi. – wmac

+0

+1, estremamente semplice. – MDMoore313

Problemi correlati