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


  • Mod

    😕 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 Methode

    void 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.


Anmelden zum Antworten