22 Stimmen

Begrenzung der Größe von Queue<T> in C++

Ich bemerke den Thread mit einer ähnlichen Frage: Begrenzung der Größe von Queue<T> in .NET? Das ist genau das, was ich tun möchte, aber ich verwende nicht .net, sondern GNU C++. Ich habe keinen Verweis auf die Basisklasse in GNU C++, also Java wie super.***() oder .net wie base.***() funktioniert nicht. Ich habe versucht, von der Warteschlangenklasse zu erben, aber es stellt sich heraus, vergeblich.

Was ich tun möchte: Die Größe der Warteschlange festlegen und die Warteschlange automatisch löschen, wenn sie voll ist. Um genau zu sein: wenn die maximale Größe meiner Warteschlange 2 ist, wenn ich das 3. Element schieben, wird das erste Element automatisch vor dem Schieben des neuen Elements herausgepoppt werden.

Wie lässt sich eine solche Warteschlange einrichten?

Gracias.

1 Stimmen

Sie müssen erklären, was Sie mit "automatischer Dequeue" meinen - meinen Sie, Dinge am Kopf der Warteschlange zu verwerfen?

0 Stimmen

@Neil: Ich wollte gerade genau die gleiche Frage stellen, aber dann habe ich zuerst auf den verlinkten Beitrag geklickt. :)

17voto

Brian Ensink Punkte 10994

Erstellen Sie eine neue Klasse, die die Warteschlange kapselt, und erzwingen Sie eine Größenbegrenzung in der neuen Klasse.

2 Stimmen

Sie meinen: eine neue Klasse mit einer Member-Variablen-Warteschlange erstellen?

0 Stimmen

@Lily, ich glaube, das ist es, worauf er hinaus will. Das ist ziemlich einfach, weil eine Warteschlange eigentlich nur zwei wichtige Mutatoren hat: push_back und pop_front. Und in Ihrem Fall, wenn es automatisch dequeues Sie möglicherweise nur push_back als ein öffentliches Mitglied benötigen.

3 Stimmen

Ich bin mit dieser Lösung nicht einverstanden, da sie die Verwendung dieser Warteschlange an Stellen verhindert, an denen eine std lib-Warteschlange erwartet wird (wie hier: template< typename T, class C> void f(std::queue<T,C>&) ). OTOH, die Verwendung von `std::queue mit einem anderen zugrundeliegenden Container wird es ermöglichen, diese Warteschlange mit ausreichend generischem Code zu verwenden, der std lib Warteschlangen erwartet.

15voto

Engineer Punkte 7950

Ich weiß, Sie sagten "automatisch", aber um die Dinge einfach zu halten: Verkapseln Sie nur die Enqueue() in einer lokalen Funktion (nein, nicht sauberes OO, aber es funktioniert):

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 Stimmen

Es handelt sich um eine Standard-Warteschlange, die ihren Zweck erfüllt (d. h. eine feste Größe der Warteschlange). Ich halte dies für die sauberste Lösung.

0 Stimmen

Übrigens ist dies eher das Format von Java. Die Klasse ist queue und die Initialisierung benötigt kein new, nur queue<T> myQueue; reicht aus und Sie müssen push, pop und size anstelle dieser Methoden verwenden.

9voto

Michael Burr Punkte 320591

Es klingt wie boost::circuclar_buffer macht, was Sie suchen:

Schreiben in einen vollen Puffer

Es gibt mehrere Möglichkeiten, damit umzugehen für den Fall, dass eine Datenquelle mehr Daten produziert, als in den festen Puffer passt:

  1. Informieren Sie die Datenquelle, dass sie warten soll, bis Platz im Puffer vorhanden ist (z. B. durch Auslösen einer Überlauf-Ausnahme).
  2. Wenn die ältesten Daten die wichtigsten sind wichtig sind, ignorieren Sie neue Daten aus der Quelle, bis Platz in der Puffer wieder Platz ist.
  3. Wenn die neuesten Daten am wichtigsten sind, überschreiben Sie die ältesten Daten.
  4. Der Produzent soll sein für die Überprüfung der Größe des des Puffers vor dem Schreiben in den Puffer.

Es ist offensichtlich, dass die circular_buffer implementiert die dritte Option. Aber es ist vielleicht weniger offensichtlich, dass sie keine der anderen Optionen umsetzt - insbesondere die ersten beiden. Man kann den den Eindruck, dass die circular_buffer sollte umsetzen die ersten drei Optionen umsetzen und einen einen Mechanismus zur Auswahl zwischen diesen Optionen anbieten. Dieser Eindruck ist falsch. Die Website circular_buffer wurde entworfen und optimiert, um zirkulär zu sein (was bedeutet Überschreiben der ältesten Daten bei voll). Wenn ein solcher Kontrollmechanismus aktiviert worden wäre, würde er einfach verkomplizieren und die Nutzung des des circular_buffer wäre wahrscheinlich weniger einfach.

0voto

sbi Punkte 211669

Unter der Annahme, dass durch Queue<T> Sie meinen std::queue<T> : Eine Warteschlange ist nur ein Adapter für einen zugrundeliegenden Container, der zur Kompilierzeit übergeben wird. Sie könnten einen Container verwenden, der bereits das tut, was Sie wollen. Am besten geeignet scheint ein Ringspeicher zu sein, wenn man einen findet, der die für die Warteschlange notwendigen Operationen unterstützt. std::queue (Ich glaube, das ist push_back() , pop_front() und size() aber ich habe es nicht überprüft).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X