1

注:これは宿題です

特に私の問題は + 代入演算子に関するものです。私は単一リンクリストテンプレートを作成しており、演算子 +=、+、-、[] などを作成する必要があります。私は配列と += を書きましたが、これまでのところ大きな問題はありませんでしたが、現在私が持っている + 演算子に取り組んでいます...

Queue.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 は正常に動作しますが、彼の関数で使用すると何か問題が発生しますか?)

  • 新しいリストを作成して、古いデータと新しいデータを入力してから、そのリストを返そうとしましたが、うまくいきませんでした。


編集: + 演算子をクラス定義から削除して、1 つのパラメーターを受け入れるようにしました。

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)、コピー コンストラクターを呼び出します。提供しないため、コンパイラが生成します。その自動生成されたコピー コンストラクターは、単にオブジェクトのフィールドごとのコピーを行います。headつまり、とtail ポインタ、および の値をコピーしますnumNodes

ただし、これは間違っています。元の要素とコピーの両方が、スコープ外に出ると同じ要素の割り当てを解除しようとするからです。これにより、未定義の動作が発生し、表示されているクラッシュが説明されます。

3 つのルールを参照してください。

于 2013-03-17T07:34:55.340 に答える