關於鏈表類指針及指針內存管理的小結

題目:

1.    請創建一個數據類型爲T的鏈表類模板List,實現以下成員函數:

1) 默認構造函數List(),將該鏈表初始化爲一個空鏈表(10分)

2) 拷貝構造函數List(const List& list),根據一個給定的鏈表構造當前鏈表(10分)

3) 析構函數~List(),釋放鏈表中的所有節點(10分)

4) Push_back(T e)函數,往鏈表最末尾插入一個元素爲e的節點(10分)

5) operator<<()友元函數,將鏈表的所有元素按順序輸出(10分)

6) operator=()函數,實現兩個鏈表的賦值操作(10分)

7) operator+()函數,實現兩個鏈表的連接,A=B+C(10分)

2.    請編寫main函數,測試該類模板的正確性:

1)     用List模板定義一個List類型的模板類對象int_listB,從鍵盤讀入m個整數,調用Push_back函數將這m個整數依次插入到該鏈表中;(4分)

2)     用List模板定義一個List類型的模板類對象int_listC,從鍵盤讀入n個整數,調用Push_back函數將這n個整數依次插入到該鏈表中;(4分)

3)     用List模板定義一個List類型的模板類對象int_listA,調用List的成員函數實現A = B + C;(4分)

4)     用cout直接輸出int_listA的所有元素(3分)

5)     用List模板定義List類型的模板類對象double_listA,double_listB, double_listC,重複上述操作。(15分)

3.    輸入輸出樣例:

1)     輸入樣例

4

12 23 34 45

3

56 67 78

3

1.2 2.3 3.4

4

4.5 5.6 6.7 7.8

2)     輸出樣例

12 23 34 45 56 67 78

1.2 2.3 3.4 4.5 5.6 6.7 7.8

我的解答:

 

#include<iostream>
using namespace std;
template<class T>//先創建一個類結構,作爲鏈表的“身體結點”
struct Node
{
 T data;
 Node<T> *next=NULL;
};
template<class T>
class List
{
public:
 
 List() { head = NULL; tail = NULL; }
 List(List<T> &list1);//複製構造函數(又名重載構造函數、拷貝構造函數)/*這個函數是這次最主要的學習點*/
 ~List()
 {
  clear();//使用單獨的清除函數利於後續使用中內存管理
 }
 void Push_back(T e);
 friend ostream &operator<<(ostream &output, List<T> list)//重載流輸出運算符
//沒注意運算符重載時使用的是引入對象以及當前對象,在引入對象List<T>list調用複製
構造函數時沒在意。這是導致本次問題遲遲沒有解決的重要原因。
 {
  List<T> t;//定義模板類時很容易遺漏<模板名>
  t.head = list.head;
  
  while (t.head)
  {
   output << t.head->data << " ";
   t.head = t.head->next;
   
  }
  return output;
 }
 List operator+(List &list1);
 List operator=(const List &list1);
private:
 
 Node<T> *head;
 Node<T> *tail;
 void clear();
 
};
template<class T>//複製構造函數的定義
List<T>::List(List &list) {
     head = NULL; tail = NULL;
/***之前忘了把新建對象的頭結點、尾節點置爲空,導致在編寫運算符重載的代碼時不斷出錯,(運算符重載時需要構造一個對象,而這個對象是通過此重載構造函數拷貝過來的)一直卡在運算符重載問題的糾正上。***/
     Node<T> *t;//新建一個臨時結點,用於讀出當前對象內容。
  t = list.head;
  while (t != NULL)
  {
   Push_back(t->data);/*在調用這個函數時也因爲內存分配問題不斷出錯!
//直接調用當前函數,所作更改均面向當前對象。
   t = t->next;
  }
  
}
template<class T>
void List<T>::clear()
{
 Node<T> *copy = head;
 while (copy != NULL)
 {
  Node<T>*t = copy;
  copy = copy->next;
  delete t;
 }
 head = tail = NULL;
}

template<class T>
void List<T> ::Push_back(T e)
{
 Node<T>* temp = new Node<T>;
 temp->data = e;
 temp->next = NULL;
 //temp->next = new Node<T>;
 if (head == NULL)
 {
  head = temp;
 }
 else
 {
  tail->next = temp;
 }
 tail = temp;
 //delete temp;
}
template<class T>
List<T> List<T>::operator+(List<T> &list1)
{
 List<T> t;
 Node<T>*tem = head;;//臨時對象tem建立
 while (tem!=NULL)
 {
  t.Push_back(tem->data);
  tem = tem->next;
 }
 tem = list1.head;
 while (tem != NULL)
 {
  t.Push_back(tem->data);
  tem = tem->next;
 }
 return t;
}/******上述函數可改進爲:
List<T> List<T>::operator+(List<T> &list1)
{
 Node<T>*tem;
 tem = list1.head;
 while (tem != NULL)
 {
  Push_back(tem->data);
  tem = tem->next;
 }
 return *this;
}

*******/

 

template<class T>
List<T> List<T>::operator=(const List<T> &list1)
{
 Node<T> *t;
 t =list1.head;
 while (t != NULL)
 {
  Push_back(t->data);
  t = t->next;
 }
 return *this;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章