在C ++中为链接列表类实现入队功能

时间:2019-03-11 23:03:58

标签: c++ class pointers linked-list queue

每个节点都存储一个指向数据类对象的指针,因此处理所有内存分配非常麻烦。

我认为问题在于入队功能的实现方式或创建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 :(得分:0)

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

您有两个名为pTail的变量。一个是成员变量Queue::pTail,但是该成员被本地参数pTail隐藏(Variable Shadowing),这是一个完全不同的变量,因为参数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的{​​{1}}从未分配给作用域更长的变量,因此在函数退出时会泄漏。另外,pData的默认行为是在失败时抛出异常,而不是返回new。由于我看不到默认行为会在任何地方被替换,因此我怀疑将永远不会使用针对nullptr的测试。

nullptr应该更像

Queue::enqueue