zoukankan      html  css  js  c++  java
  • Cpp Chapter 12: Classes and Dynamic Memory Allocation Part3

    12.7 A queue simulation

    ) queue: FIFO(first in first out), just like regular queue in the waiting line
    ) stack: LIFO(last in first out), just like a pile of plates
    ) The queue class interface
    decide a set of attributes of the queue class(the public interface)
    ) The queue class implementation
    use a linked list to represent a queue. A linked list consists of a sequence of nodes, each node contains the information to be held in the list, plus a pointer to the next in the list

    struct Node
    {
        Item item;
        struct Node * next;
    }
    

    The example code shows a singly linked list because each node has a single link to the next node. The pointer in the last node points to NULL or 0, or with C++11 nullptr keyword.
    A data member of the Queue class should point to the first Node of a queue. For convenience, you could also have data members for the last node and the number of nodes in the queue(for quickly adding nodes and detecting full and empty and limit of nodes amount). Also a data member should represent the maximum amount of nodes allowed in the queue.

    class Queue
    {
    private:
        struct Node { Item item; struct Node * next;};
        enum {Q_SIZE = 10};
        Node * front;
        Node * rear;
        int items;
        const int qsize;
        ...
    public:
        ...
    }
    

    ) Code:

    class Queue
    {
    private:
        struct Node { Item item; struct Node * next;};
    ...
    }
    

    nest the struct in the class, giving it class scope to avoid conflict with STL(standard template library).

    ) The class methods
    Recall that you could only initialize a const variable, rather than assign it to specific value. Thus making the constructor

    Queue::Queue(int qs)
    {
        ...
        qsize = qs;
    }
    

    invalid to assign qsize to qs. For that sake, C++ provides member initializer list:

    Queue::Queue(int qs) : qsize(qs)
    {
        ...
    }
    

    which follow the regular constructor with the syntax of " : var(val)". You also have to use member initializer list with references for class members. This syntax could only be used with constructors.

    Adding members to queue:
    1 terminate if the queue is full
    2 create a new node
    3 place proper values into the node
    4 increase the amount of nodes
    5 attach the node to the rear of the sequence

    Removing members in queue
    1 terminate if the queue is empty
    2 save the item of the first node to the passed reference to the function
    3 decrease Node count
    4 save the location of front node(for later deletion)
    5 take the node off the queue by "front = front->next"
    6 delete former first node
    7 if list empty, set rear to NULL

    )Other class methods
    An explicit destructor which guarantee that a queue would be empty when it expires
    A copy constructor and overloading the assignment operator is also required, but you could escape this now:

    class Queue
    {
    private:
        Queue(const Queue & q) : qsize(0) { }
        Queue & operator=(const Queue & q) { return *this;}
    ...
    }
    

    Define these methods as private prevents outside from accessing the methods, thus forbidding Queue copy and assignment. Pass objects by reference to avoid this problem

    ) The customer class
    You need to use data members to represent the customer's arrive time, process time, and provide a function in the public interface to set the data

    Here comes the example:

    // queue.h -- interface for a queue
    #ifndef QUEUE_H_INCLUDED
    #define QUEUE_H_INCLUDED
    
    class Customer
    {
    private:
        long arrive;
        int processtime;
    public:
        Customer() {arrive = processtime = 0;}
        void set(long when);
        long when() const {return arrive;}
        int ptime() const {return processtime;}
    };
    
    typedef Customer Item;
    
    class Queue
    {
    private:
        struct Node {Item item; struct Node * next;};
        enum {Q_SIZE = 10};
    
        Node * front;
        Node * rear;
        int items;
        const int qsize;
    
        Queue(const Queue & q); // prevent outside access to copy constructor
        Queue & operator=(const Queue & q) {return *this;} // prevent outside access to assignment operator
    public:
        Queue(int qs = Q_SIZE);
        ~Queue();
        bool isempty() const;
        bool isfull() const;
        int queuecount() const;
        bool enqueue(const Item & item);
        bool dequeue(Item & item);
    };
    #endif // QUEUE_H_INCLUDED
    
    // queue.cpp -- Queue and Customer methods
    #include "queue.h"
    #include <cstdlib>
    
    Queue::Queue(int qs) : qsize(qs)
    {
        front = rear = NULL;
        items = 0;
    }
    
    Queue::~Queue()
    {
        Node * temp;
        while (front != NULL)
        {
            temp = front;
            front = front->next;
            delete temp;
        }
    }
    
    bool Queue::isempty() const
    {
        return items == 0;
    }
    
    bool Queue::isfull() const
    {
        return items == qsize;
    }
    
    int Queue::queuecount() const
    {
        return items;
    }
    
    bool Queue::enqueue(const Item & item)
    {
        if (isfull()) return false;
        Node * add = new Node;
        add->item = item;
        add->next = NULL;
        items++;
        if (front == NULL)
            front = add;
        else
            rear->next = add;
        rear = add;
        return true;
    }
    
    bool Queue::dequeue(Item & item)
    {
        if (isempty()) return false;
        Node * temp = new Node;
        temp = front;
        item = front->item;
        items--;
        front = front->next;
        delete temp;
        if (items == 0)
            rear = NULL;
        return true;
    }
    
    void Customer::set(long when)
    {
        processtime = std::rand() % 3 + 1;
        arrive = when;
    }
    
    // queue.cpp -- Queue and Customer methods
    #include "queue.h"
    #include <cstdlib>
    
    Queue::Queue(int qs) : qsize(qs)
    {
        front = rear = NULL;
        items = 0;
    }
    
    Queue::~Queue()
    {
        Node * temp;
        while (front != NULL)
        {
            temp = front;
            front = front->next;
            delete temp;
        }
    }
    
    bool Queue::isempty() const
    {
        return items == 0;
    }
    
    bool Queue::isfull() const
    {
        return items == qsize;
    }
    
    int Queue::queuecount() const
    {
        return items;
    }
    
    bool Queue::enqueue(const Item & item)
    {
        if (isfull()) return false;
        Node * add = new Node;
        add->item = item;
        add->next = NULL;
        items++;
        if (front == NULL)
            front = add;
        else
            rear->next = add;
        rear = add;
        return true;
    }
    
    bool Queue::dequeue(Item & item)
    {
        if (isempty()) return false;
        Node * temp = new Node;
        temp = front;
        item = front->item;
        items--;
        front = front->next;
        delete temp;
        if (items == 0)
            rear = NULL;
        return true;
    }
    
    void Customer::set(long when)
    {
        processtime = std::rand() % 3 + 1;
        arrive = when;
    }
    

  • 相关阅读:
    WinDbg 调试工具的使用
    多线程间通信之AutoResetEvent和ManualResetEvent的原理分析和开发示例
    Oracle Database 11g Release 2 (11.2) Installation On Oracle Linux 6
    软件项目管理解决方案(转)
    iis应用程序池 内存溢出错误 System.OutOfMemoryException(转)
    今天遇到Oracle审计表AUD$数据过大问题
    从完好的数据文件恢复oracle数据库
    ORA12518 TNS:监听程序无法分发客户机连接 解决办法(转)
    RHEL 5防火墙说明
    example how to build RPM package from source package
  • 原文地址:https://www.cnblogs.com/fsbblogs/p/9807992.html
Copyright © 2011-2022 走看看