【问题标题】:help with linked list template链接列表模板的帮助
【发布时间】:2011-04-08 03:00:54
【问题描述】:

我的链接列表需要一些帮助。我认为问题出在复制构造函数或赋值重载中。当我打电话时,它一直给我的分段错误: (队列 test_int_copy(test_int);) 您可以看到的任何其他错误或糟糕的实现也将非常有帮助。 .h 文件

#ifndef QUEUE_H
#define QUEUE_H

template <class Object>
class Queue
{
 public:
     Queue();
     //initializes empty queue

     Queue(const Queue& a_queue);
     //copy constructor

     Queue& operator =(const Queue& rhs);
     //overload assignment operator

     bool enqueue(const Object& d);
     //insert object into queue,return true
     //return false if not

     bool dequeue(Object& d);
     //remove object from queue,return true
     //if empty return false

     bool isEmpty();
     //check if empty

     ~Queue();
     //destructor

private:
    struct ListNode
    {
        Object obj;
        //object that is in the list

        ListNode *next;
        //pointer to the next node

    };
    //struct of list

    ListNode *head;
    //pointer that points to head
};

#endif //Queue_H
#include "queue.cpp"  //include queue.cpp with file

.cpp 文件

     #include <iostream>
using namespace std;

template <class Object>
Queue<Object>::Queue()
{
    head = NULL;
}

template <class Object>
Queue<Object>::Queue(const Queue<Object> &a_queue)
{
    head = NULL;
  ListNode *nodePtr = a_queue.head;
    while (nodePtr){
      enqueue(nodePtr->obj);
      nodePtr = nodePtr->next;
    }

}

template <class Object>
Queue<Object>& Queue<Object>::operator =(const Queue<Object> &rhs)
{
    //head = NULL;
  ListNode *nodePtr = rhs.head;
  Object temp;
    while(head){
      dequeue(temp);
    }
    while (nodePtr){
      enqueue(nodePtr->obj);
      nodePtr = nodePtr->next;
    }
}

template <class Object>
bool Queue<Object>::enqueue (const Object& d) //Enqueue
{
    ListNode *newNode = new ListNode;
    newNode->obj = d;
    newNode->next = NULL;
    ListNode *nodePtr = NULL;
    ListNode *previousNode = NULL;

    if(isEmpty()){
        head = newNode;
        return true;
        }
    else{
        nodePtr = head;
        while(nodePtr != NULL){
            previousNode = nodePtr;
            nodePtr = nodePtr->next;
        }
        if(previousNode->next == NULL){
            previousNode->next = newNode;
            return true;
        }
        else
            return false;
    }
}

template <class Object>
bool Queue<Object>::dequeue (Object& d)  //Dequeue
{
    ListNode *nodePtr;

    if(!head)
        return false;
    else{
      if(head->next != NULL){
            nodePtr = head;
            d = nodePtr->obj;
            head = head->next;
            delete nodePtr;
            return true;
      }
      else{
        d = head->obj;
        head = NULL;
        return true;
      }
    }
}


template <class Object>
bool Queue<Object>::isEmpty() //Check if Empty
{
    if(!head)
        return true;
    else
        return false;
}

template <class Object>
Queue<Object>::~Queue()   //Destructor
{
    Object temp;
    while(head)
        dequeue (temp);
}

【问题讨论】:

    标签: c++ g++ linked-list


    【解决方案1】:

    也不要像那样包含源文件。或者,如果您坚持,请确保将其放在包含保护中。例如

    #include "queue.cpp"  //include queue.cpp with file
    #endif //Queue_H
    

    否则,如果多次包含标头(这种情况一直都在发生),则会出现编译错误。 (STuff 将被多次定义)。

    此外,如果您要在标头中包含“源”——请确保所有函数都是“内联”(隐式或显式),否则会出现链接器错误

    【讨论】:

      【解决方案2】:

      您应该在复制构造函数中初始化您的头指针(顺便说一下,在您的 operator = 函数中)。如果你不这样做,head 可能会以一个未定义的值结束并且无法通过 IsEmpty 测试,这可能会导致 enqeue 崩溃。

      【讨论】:

        【解决方案3】:

        我可以看到一个错误:在 dequeue() 方法中,您在删除最后一项后没有将 head 设置为 NULL。

        另外,在赋值重载中:

        while(head){
              dequeue(temp);
              head = head->next;
            }
        

        ...你不需要设置head = head->next,已经通过dequeue()方法完成了。

        【讨论】:

        • “删除头”不会使头为空吗??
        【解决方案4】:
        1. 您的enqueue() 函数总是在最后插入一个节点。所以最好保持一个额外的成员变量为:ListNode *tail;指向列表的最后一个节点。因此,当您添加节点时,您无需遍历整个列表,只需更新*tail。这将节省大量时间。
        2. 无论出于何种原因从enqueu() 返回false,都不要忘记delete newNode;,否则会泄漏内存。
        3. isEmpty() 可以简化为bool isEmpty() { return (0 != head); }
        4. 不用在dequeue() 中声明和传递原始对象,如果元素被删除,您可以简单地返回Object*,如果元素为空,则返回0 (NULL);这相当于truefalse
        5. 重要的是,无论何时你delete head; 总是做head = 0;。因为那是一个成员变量,不应该是悬空的。

        【讨论】:

          猜你喜欢
          • 2018-02-09
          • 1970-01-01
          • 2013-02-12
          • 1970-01-01
          • 2015-12-26
          • 1970-01-01
          • 1970-01-01
          • 2011-01-20
          • 1970-01-01
          相关资源
          最近更新 更多