注意:这是家庭作业
具体来说,我的问题是+赋值运算符,我正在编写一个单链列表模板,必须创建运算符+=、+、-、[]等等。我已经编写了数组,到目前为止+=没有太大问题,但现在我正在处理+运算符目前我有。。。
队列.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
main.cpp
#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!
分段故障(堆芯转储(
我需要实现+运算符,这样它就会接收一个数据指针,并返回一个由旧列表和新节点组成的新列表。我在类模板中编写了这个函数,因为我读到在外部编写它是一个问题,就像我的其他函数一样。我试了几种方法让发挥作用
使用我定义的+=赋值运算符(plus equals可以很好地工作,但当我将其与他的函数一起使用时,会出现问题吗?(
我试着创建一个新列表,并用新旧数据填充它,然后返回该列表,但没有成功。。所以现在我很困惑,一个指向正确方向的点会很可怕!
编辑:我已经尝试从类定义中删除我的+运算符,并将其简化为接受一个参数
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;
}
在我对它的所有测试中,这似乎是"有效的",但在我的测试结束时(在所有输出正确后(,出现了一个分段故障
您需要为类定义一个复制构造函数和一个赋值运算符。这些将需要逐个元素复制整个列表。
在以下代码中:
Queue<T> *temp = (Queue<T> *) new Queue<T>(*this);
CCD_ 1调用复制构造函数。由于您没有提供一个,编译器会为您生成一个。自动生成的复制构造函数只需对对象进行逐字段的复制。换句话说,它复制head
和tail
指针,以及numNodes
的值。
然而,这是错误的,因为当相同的元素超出范围时,原始元素和副本都会试图解除分配。这导致了未定义的行为,并解释了您所看到的崩溃。
请参阅"三条规则"。