1

注意:这是作业

具体来说,我的问题是 + 赋值运算符,我正在编写一个单链表模板,并且必须创建运算符 +=、+、-、[] 等。我已经编写了数组,并且 += 到目前为止没有太多问题,但现在我正在使用 + 运算符,目前我有......

队列.h

#ifndef QUEUE_H
#define QUEUE_H

#include<iostream>
//#include "UnderGrad.h"
//#include "Grad.h"
#include <string.h>
#include<cstdlib>

template <typename T>
class Queue
{
class Node
{
    friend class Queue;
    private:
    T* data;
    Node* next;
};

public:
    Queue() {head = NULL; tail = NULL; numNodes = 0;}
    ~Queue () {clear();}

    //overloaded operators
    T& operator [] (int);
    const T& operator [] (int) const;
    Queue<T>& operator += (T*);
    Queue<T>& operator += (Queue<T>&);
    friend Queue<T> operator+ (Queue<T> inList,T* tbAdded)
    {
        inList.pushBack(tbAdded);

        return inList;
    }
    //Queue<T> operator + (Queue<T>, Queue<T>&);
    //Queue<T>& operator -= (T*&);
    //Queue<T>& operator -= (const Queue<T>&);
    //Queue<T> operator - (T, const T&);
    //Queue<T> operator -(Queue<T>, const Queue<T>&);
    //Queue<T>& operator ! ();



    void pushBack(T*);
    //nice to be ble to clear all sometimes rather than write a for loop evertime you want ot clear the list
    void clear();
    void popFront();

    bool empty();
    T* front();
    int size() const;

    //used while an individual is using create app, so you can go back and edit prevous pages of the app
    T* getPrev(T*);
    T* back();
    void removeNode(T*);
    void sortList();

private:
Node* head;
Node* tail;
int numNodes;

};


//be carefule here with automatic variables
//as it will not create a new instance
template <typename T>
Queue<T>& Queue<T>::operator += (T* tbAdded)
{
    this -> pushBack(tbAdded);
return *this;
}


template <typename T>
Queue<T>& Queue<T>::operator += (Queue<T> &tbAdded)
{   
T* temp;

while (tbAdded.front() != NULL)
{
    temp = (T*) new T(*(tbAdded.front()));
    this -> pushBack(temp);
    tbAdded.popFront();
}

return *this;
}

template <typename T>
const T& Queue<T>::operator[] (int index) const
{
int count = 0;
Node *temp = head;

while (count < index && temp -> next != NULL)
{
    count++;
    temp = temp -> next;
}

if (count < index)
{
    std::cerr << "ArrayOutOfBounds: Index at: " << index << " ArrayLength: " << count << std::endl;
    exit(1);
}
else
{
    return *(temp -> data);
}
}

template <typename T>
T& Queue<T>::operator[] (int index)
{
int count = 0;
Node *temp = head;

while (count < index && temp -> next != NULL)
{
    count++;
    temp = temp -> next;
}

if (count < index)
{
    std::cerr << "ArrayOutOfBounds: Index at: " << index << " ArrayLength: " << count << std::endl;
    exit(1);
}
else
{
    return *(temp -> data);
}
}



//adds node to the back of the list
template <typename T>
void Queue<T>::pushBack(T *tbAdded)
{
    //  std::cout << "hello" << std::endl;

Node *temp = new Node;
//I copy the data into the heap, because for some operations i want to use save   local variables which poses problematic
temp -> data = tbAdded;
temp -> next  = NULL;
    //  std::cout << "hello" << std::endl;
if (head == NULL)
{
    //  std::cout << "bye" << std::endl;
    head = temp;
    tail = head;
}   
else
{
    //  std::cout << "shy" << std::endl;
    tail -> next = temp;
    tail = tail -> next;

}
    //  std::cout << "hello" << std::endl;
numNodes++;
}

//returns length of Queue
template <typename T>
int Queue<T>::size() const
{
return numNodes;
}


//removes a node formt he fornt of the list
template <typename T>
void Queue<T>::popFront()
{
if (head != NULL)
{
    Node *temp = head;
    head = head ->next;
    delete (temp -> data);
    delete (temp);
    numNodes--;
    if (numNodes > 0)
    {
        numNodes--;
        if (numNodes == 0)
        {
            tail = NULL;
        }
    }
}
}

//clears the list
template <typename T>
void Queue<T>::clear()
{
while (head != NULL)
{
    popFront();
}
}

//returns true iff list is empty
template <typename T>
bool Queue<T>::empty()
{
if (numNodes == 0)
{
    return true;
}

return false;
}


//returns data at fornt of list unless the list is empty then it returns null
template <typename T>
T* Queue<T>::front()
{
if (head != NULL)
{
    return head -> data;
}
else
{
    return NULL;
}
}

 //sorts undgrad info
//template <>
//inline void Queue<UnderGrad>::sortList()
//{
//  Node *temp = head;
//  UnderGrad *info;
//
//  for (int i = 0; i < size(); i++)
//  {
//      while (temp -> next)
//      {
//          std::string temp1 = (*(temp -> data)).getCourse();
//          std::string temp2 = (*(temp -> next -> data)).getCourse();
//          if (strcmp(temp1.c_str(), temp2.c_str()) > 0)
//          {
//              info = temp -> data;
//              temp -> data = temp -> next -> data;
//              temp -> next -> data = info;
//
//          }
//          else if (strcmp(temp1.c_str(), temp2.c_str()) == 0 && 
//              (*(temp -> data)).getGPA() < (*(temp -> next -> data)).getGPA())
//          {
//              info = temp -> data;
//              temp -> data = temp -> next -> data;
//              temp -> next -> data =    info;                 
//          }
//
//          temp = temp -> next;
//      }
//      
//      temp = head;
//  }
//  
//
//  
//}


//sorts Grad info
//template <>
//inline void Queue<Grad>::sortList()
//{
//  Node *temp = head;
//  Grad *info;
//
//  for (int i = 0; i < size(); i++)
//  {
//      while (temp -> next)
//      {
//          std::string temp1 = (*(temp -> data)).getCourse();
//          std::string temp2 = (*(temp -> next -> data)).getCourse();
//          std::string temp3 = (*(temp -> data)).getResearch();
//          std::string temp4 = (*(temp -> next -> data)).getResearch();
//          if (strcmp(temp1.c_str(), temp2.c_str()) > 0)
//          {
//              info = temp -> data;
//              temp -> data = temp -> next -> data;
//              temp -> next -> data = info;
//
//          }
//          else if (strcmp(temp1.c_str(), temp2.c_str()) == 0 && 
//              strcmp(temp3.c_str(), temp4.c_str()) > 0)
//          {
//              info = temp -> data;
//              temp -> data = temp -> next -> data;
//              temp -> next -> data = info;                    
//          }
//
//          temp = temp -> next;
//      }
//      temp = head;
//  }
//  
//
//  
//}


//these mothds i was considering using for a bonus but never completed they are used   no where in my code for now atleast
//this method is used when a back button is pressed so i can go from end to front of a list (since this is supposed to be a singly linked list this will be inneficient)
//that way if i have multiple things i.e related courses saved i can go back and edit  them b4 i save the app
template <typename T>
T* Queue<T>::getPrev(T* curNode)
{
if (curNode == head)
{
    return NULL;
}

Node *temp = head;
while (temp -> next != curNode)
{
    temp = temp -> next;
}

return temp -> data;
}


//if editing data i need a acces the last node in order to be able to go back and eit nodes back -> front
template <typename T>
T* Queue<T>::back()
{
if (tail != NULL)
{
    return head -> data;
}
else
{
    return NULL;
}
}

//if we decide to go back and edit we will need to remove the old node
template <typename T>
void Queue<T>::removeNode(T *tbRemoved)
{
Node *curNode, *prevNode;

curNode = head;

if (tbRemoved == head -> data)
{
    head = head -> next;
    delete curNode -> data;
    delete curNode;
}

while (curNode -> data != tbRemoved)
{
    prevNode = curNode;
    curNode = curNode -> next;
}

prevNode -> next = curNode -> next;
delete curNode -> data;
delete curNode;
}

#endif 

主文件

#include"Queue.h"
#include<iostream>

using namespace std;

int main()
{
Queue<int> intList;
Queue<int> intList1, intList2;
int *t;

intList.pushBack((int*) new int (5));
intList.pushBack((int*) new int (10));
intList.pushBack((int*) new int (15));
intList.pushBack((int*) new int (20));


intList += ((int*) new int (25));
cout << intList[4] << "!" << endl;
cout << "?" << endl;
cout << "?" << endl;
cout << "?" << endl;
intList = intList + ((int*) new int (35));
cout << intList[5] << "!" << endl;
intList += ((int*) new int (30));
cout << intList[5] << "!" << endl;
cout << "?" << endl;
cout << "?" << endl;
cout << "?" << endl;

intList1.pushBack((int*) new int (2));
intList1.pushBack((int*) new int (7));
intList1.pushBack((int*) new int (9));
intList1.pushBack((int*) new int (11));
intList += intList1;
    intList1.clear();
cout << intList[6] << "!" << endl;
cout << intList[2] << "!" << endl;
intList.clear();
intList1.clear();
cout << "?" << endl;


Queue<string> strList;
cout << "?" << endl;    
strList.pushBack((string*) new string("hi"));
strList.pushBack((string*) new string("bi"));
strList.pushBack((string*) new string("di"));
strList.pushBack((string*) new string("ki"));
cout << "?" << endl;
cout << strList[2] << "!" << endl;
return 0;
}

输出:25!

?

?

?

分段错误(核心转储)

我需要实现 + 运算符,因此它接受一个数据指针并返回一个由旧列表和新节点组成的新列表,我在类模板本身中编写了这个函数,因为我读到它是在外面写它的问题,比如我的其余功能。我已经尝试了一些方法来让它工作

  • 使用我定义的 += 赋值运算符(加号可以正常工作,但是当我将它与他的函数一起使用时出现问题?)

  • 我已经尝试创建一个新列表并用旧数据和新数据填充它,然后返回该列表,但没有用..所以现在我混淆了正确方向的点会很糟糕!


编辑:我尝试从类定义中删除我的 + 运算符并将其减少为接受一个参数

template <typename T>
Queue<T>& Queue<T>::operator+ (T* tbAdded)
{
Queue<T> *temp = (Queue<T> *) new Queue<T>(*this);
temp -> pushBack(tbAdded);
  //    std::cout << (*temp)[5] << std::endl;
  //    std::cout << (*this)[3] << std::endl;
return *temp;
}

形成我所有的测试,这似乎是“工作”,但是在我的测试结束时(在所有输出正确输出之后)存在分段错误

4

1 回答 1

1

您需要为您的类定义一个复制构造函数和一个赋值运算符。这些将需要逐个元素地复制整个列表。

在以下代码中:

Queue<T> *temp = (Queue<T> *) new Queue<T>(*this);

Queue<T>(*this)调用复制构造函数。由于您不提供,编译器会为您生成一个。该自动生成的复制构造函数只是对您的对象进行逐个字段的复制。换句话说,它复制headtail 指针,以及 的值numNodes

然而,这是错误的,因为当原始元素和副本超出范围时,它们都会尝试释放相同的元素。这会导致未定义的行为,并解释您所看到的崩溃。

三法则

于 2013-03-17T07:34:55.340 回答