Queue
-
Guten Abend allerseits!
Ich versuche mich etwas in die Queue-Theorie einzuarbeiten und habe folgenden Code (fast) fertig zusammen.
Im main-Source-Code muss ich noch ein Argument einfügen, das mir irgendwie nicht bekannt ist. D.h. ich weiss nicht genau, welch Argument der Compiler gerne hätte.Hier die wichtigsten Snippets:
ticket-system.cpp// ... void ticket_system::populate_free_counters(customer **customer_) { /* Remove the next customer from the ticket queue and assign him to the next free counter. Do that for all free counters. */ _ticket_queue.remove(customer_); for(unsigned int i = 0; i < _counters.size()+1; i++) { if(_counters.at(i)->is_free()) { enqueue_customer(*customer_); } } }
main.cpp:
ticket_system post_office; // ... customer tom("tom"); //.. post_office.enqueue_customer(&tom); //.. while( ! post_office.is_ticket_queue_empty() ) { post_office.complete_random_counter_service(); post_office.populate_free_counters(); // Hier muss ein Argument rein. Aber welches? (0 würde gehen, das Programm läuft dann auch, bis ein Fehler auftritt.) }
Vielen Dank und Gruss,
Raffi
-
Das musst du schon selber wissen, was dein eigener Code machen soll. Aus den Namen kann ich mir zwar erschließen um was es geht (die sind gut gewählt
), aber wie sollen wir dir deine eigenen Klassen und Funktionen erklären?
-
Da wird wohl irgend ein Dummkopf in C++ ein C-Array mit Zeigern auf Customer benutzt haben:
customer* customers[10]; ... post_office.populate_free_counters(customers);
-
schade ich finde den Link auf c/c++ Sterne Programmierer nimmer
... guck dir mal die STL an, da gibts sowas fertig. Wenn du das selbst machst um zu üben, hindert dich trotzdem kaum jemand daran einen std::vector/list/whatever und Objekte statt Pointern zu nutzen. Was das fehlende Argument angeht .. schau dir die Methode an die aufgerufen wird, dann weisst du was fehlt.
-
Hm. Das regt mich momentan ziemlich auf, weil alles super funktioniert, bis auf dieses Problem hier.
Ich habe nun den Code wiefolgt verändert. Ich poste hier mal alle Methoden / Source-Codes, mit welchen meine fehlerhafte Methode in Verbindung steht.
ticket_system.cpp:
// ... void ticket_system::populate_free_counters() { /* Remove the next customer from the ticket queue and assign him to the next free counter. Do that for all free counters. */ customer* customer_; _ticket_queue.remove(&customer_); for(unsigned int i = 0; i < _counters.size()+1; i++) { if(_counters.at(i)->is_free()) { enqueue_customer(customer_); } } }
ticket_system.hpp:
#ifndef TICKET_SYSTEM_HPP #define TICKET_SYSTEM_HPP #include "counter.hpp" #include "queue.hpp" #include "customer.hpp" class ticket_system { private: std::vector<counter*> _counters; queue _ticket_queue; int _current_ticket_number; public: ticket_system(int number_of_counters_ = 3); ~ticket_system(); void enqueue_customer(customer*); bool is_ticket_queue_empty() const; void complete_random_counter_service(); void populate_free_counters(); void print_ticket_queue() const; }; #endif // TICKET_SYSTEM_HPP
main.cpp:
ticket_system post_office; // ... customer tom("tom"); //.. post_office.enqueue_customer(&tom); //.. while( ! post_office.is_ticket_queue_empty() ) { post_office.complete_random_counter_service(); post_office.populate_free_counters(); }
-
Ok. Dieses Problem konnte ich mittlerweile lösen.
Allerdings habe ich in queue noch einen Fehler, den ich nicht finde:
queue.cpp:#include "queue.hpp" queue::queue() : _tail_index(0) { } int head = 0; int _tail_index = 0; void queue::add(customer* new_element_) throw(queue_full_exception) { /* add the passed element to this queue, i.e. to the _elements class variable */ if(_tail_index < head + QUEUE_SIZE) { _elements[_tail_index] = new_element_; _tail_index++; } else throw new queue_full_exception; } customer* queue::remove() throw(queue_empty_exception) { /* remove the first element from the queue */ if(_tail_index == head) { throw new queue_empty_exception; } else { _elements[head] = NULL; head ++; head %= QUEUE_SIZE; } } bool queue::is_empty() const { /* return true if the queue is empty, false otherwise */ if(QUEUE_SIZE == 0) { return true; } else { return false; } }
queue.hpp:
#ifndef QUEUE_HPP #define QUEUE_HPP #include <vector> #include "queue_full_exception.hpp" #include "queue_empty_exception.hpp" #include "customer.hpp" #define QUEUE_SIZE 20 class queue { private: customer* _elements[QUEUE_SIZE]; int _tail_index; // the index of the element past the last element public: queue(); void add(customer*) throw(queue_full_exception); customer* remove() throw(queue_empty_exception); bool is_empty() const; }; #endif // QUEUE_HPP
Hat ihn jemand gefunden?
-
Ist hier OSTERN? Ist da ein EI VERSTECKT?
...
Zu Fehlern gehören Fehlermeldungen - und ne gute Beschreibung.
-
Ja, du hast natürlich Recht.
Also das Problem liegt in der Methodevoid ticket_system::populate_free_counters()
aus dem vorletzten Post. Ich muss dort einen customer zu einem freien counter schicken. Allerdings klappt das nicht so, wie ich es dort gemacht habe.
-
throw(queue_full_exception)
Auf Exception-Spezifikationen würde ich verzichten. Sie versprechen mehr als sie halten und bringen eine Menge Nachteile. In C++0x sind sie deprecated.
throw new queue_full_exception;
Exceptions als Zeiger werfen würde ich erst recht nicht, schon gar nicht wenn der Speicher nirgends freigegeben wird.
_elements[head] = NULL;
Falls an dieser Stelle ein mit
new
angefordertes Objekt war, hast du ein weiteres Memory Leak.if(QUEUE_SIZE == 0) { return true; } else { return false; }
Das geht in einer Zeile mit
return QUEUE_SIZE == 0;
. Davon abgesehen siehst du an der Grossschreibung, dass es sich um eine Konstante handelt, was sinnlos ist.customer* _elements[QUEUE_SIZE];
Warum hier überhaupt Zeiger und nicht
customer
als Elementtyp? Abgesehen davon solltest du führende Unterstriche meiden, weil es sich um reservierte Bezeichner handeln kann.