Реализация функции enqueue для класса связанного списка в C ++ - PullRequest
0 голосов
/ 12 марта 2019

Каждый узел хранит указатель на объект класса данных, поэтому работает со всем распределением памяти, и это очень запутанно.

Думаю, проблема в том, как была реализована функция enqueue, или что-то не так с созданием объекта Node или созданием объекта Data. Так как я не уверен в указателях, это также может быть проблемой, так как я мог бы назначать вещи неправильно.

То, что в итоге происходит, состоит в том, что очередь получает только один узел после добавления множества узлов в очередь. (используется в симуляции продуктового магазина)

//Add data to front 
bool Queue::enqueue(Data newData) {
    return this->enqueue(this->pTail, newData);
}
bool Queue::enqueue(Node * pTail, Data newData) {
    //If queue is empty, head and tail point to the new Node
    Data * pData = new Data(newData);
    //Test if data was allocated to heap
    if (pData == nullptr) {
        return false;
    }
    //If empty
    if (pTail == nullptr) {
        pTail = new Node(pData);
        this->pHead = pTail;
    }
    //If queue isnt empty
    else {
        //Add new node to the old end, then set new end to new node
        pTail->setPNext(new Node(pData));
        pTail = pTail->getPNext();
    }
    return true;
}

Класс узла

class Node {
private:
    Data * pData;    
    Node * pNext;
public:
    Node() {
        pNext = nullptr;
    }
    Node(Data * n) {
        pData = n;
        pNext = nullptr;
    }
    ~Node() {
    }
    //Setter
    void setPNext(Node * newPNext) {
        pNext = newPNext;
    }
    void setData(Data newData) {
        pData->setData(&newData);
    }
    //Getters here

Класс данных

class Data {
private:
    int customerNumber;
    int serviceTime;   
    int totalTime;    
public: 
    Data() {
    }
    Data(int n, int s, int tPrev) {
        customerNumber = n;
        serviceTime = s;
        totalTime = tPrev;
    }
    Data(Data &d) {
        customerNumber = d.getCNum();
        serviceTime = d.getSTime();
        totalTime = d.getTotalTime();
    }
    Data &operator= (Data &d) {
        customerNumber = d.getCNum();
        serviceTime = d.getSTime();
        totalTime = d.getTotalTime();

        return *this;
    }

Реализация класса Queue должна быть в порядке, поэтому я не буду включать его здесь.

Внутри main точка данных создается и добавляется в очередь

    //Create new customer data (ints)
    Data newData(newCustomerNumber, newExpressTime, totalExpressTime);

    //Add customer to queue
    express.enqueue(newData);

1 Ответ

0 голосов
/ 12 марта 2019

В

bool Queue::enqueue(Node * pTail, Data newData)

У вас есть две переменные с именем pTail. Одним из них является переменная-член Queue::pTail, но этот член скрыт ( Затенение переменной ) локальным параметром pTail, совершенно другой переменной, поскольку параметр pTail был определен в более близкой области.

Node, на который указывает параметр pTail, передается по ссылке и является тем же Node, на который указывает Queue::pTail, но сам pTail передается по значению и является просто копией адреса это значение Queue::pTail. Это означает, что когда вы повторяете pTail, с

pTail = new Node(pData);

например, pTail копия повторяется. Оригинал в вызывающей функции остается без изменений.

Решение:

Также передайте указатель по ссылке. Изменить

bool Queue::enqueue(Node * pTail, Data newData)

до

bool Queue::enqueue(Node *& pTail, Data newData)

Примечания:

Data * pData = new Data(newData);
if (pData == nullptr) {
    return false;
}

Ничего полезного не делает. Data, присвоенный pData, никогда не назначается переменной с более длинной областью действия, поэтому он пропускается при выходе из функции. Кроме того, поведение по умолчанию new - генерировать исключение при сбое, а не возвращать nullptr. Поскольку я не вижу, чтобы поведение по умолчанию заменялось где-либо, я подозреваю, что тест для nullptr никогда не будет использован.

Queue::enqueue должно выглядеть как

bool Queue::enqueue(Node *& pTail, Data newData) {
    if (pTail == nullptr) {
        pTail = new Node(pData);
        this->pHead = pTail;
    }
    else {
        pTail->setPNext(new Node(pData));
        pTail = pTail->getPNext();
    }
    return true;
} 
...