在C 中实现链接列表类的临界功能

Implementing an enqueue function for a Linked list class in C++

本文关键字:功能 列表 实现 链接      更新时间:2023-10-16

每个节点存储一个指向数据类的对象,因此使用所有内存分配,这是非常令人困惑的。

我认为问题是对入口函数的实现方式或创建节点对象或数据对象的创建的方式。由于我对指针的信心也可能是一个问题,因为我可能会不正确地分配事情。

最终发生的事情是队列在队列中添加许多节点后仅获取一个节点。(在杂货店模拟中使用)

//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;
    }

队列类的实现应该很好,所以我不会在这里包含它。

在MAIN中,创建数据点,然后添加到队列

    //Create new customer data (ints)
    Data newData(newCustomerNumber, newExpressTime, totalExpressTime);
    //Add customer to queue
    express.enqueue(newData);

in

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

您有两个名为pTail的变量。一个是成员变量Queue::pTail,但是该成员是由本地参数pTail(一个完全不同的变量)隐藏的(变量阴影),因为参数pTail是在更近的范围中定义的。

由参数pTail指向的Node通过引用传递,并且NodeQueue::pTail点相同,但是pTail本身是按值传递的,仅是Queue::pTail值的地址的副本。这意味着当您重点 pTail时,使用

pTail = new Node(pData);

例如,pTail复制重新命令。调用功能中的原始功能保持不变。

解决方案:

也通过参考将指针传递。更改

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

to

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

旁注:

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

没有做任何有用的事情。分配给pDataData永远不会分配给具有更长范围的变量,因此当功能退出时,它会泄漏。此外,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;
}