2015-05-26 56 views
-1

我有一個關於C++數據結構的作業,但遇到了一個奇怪的問題。對不起,如果標題有點不明顯。首先,爲了完成作業,我們給了一個PaperRepository類的頭文件來實現。本課程通過一個循環雙向鏈表列出論文的信息。每篇文章都有標題,在該論文發表期刊,出版年份和共同作者的列表是由另一個鏈表類(有序鏈表)舉行,這裏是PaperRepository.h文件C++意外的析構函數調用

// PaperRepository.h 

#include <string> 

#include "CDoublyLinkedList.cpp" 
#include "Paper.cpp" 

using std::string; 

class PaperRepository 
{ 
public: 
    PaperRepository(); 
    ~PaperRepository(); 

    void addPaper(string paperTitle, string journalTitle,int publicationYear); 
    void removePaper(string paperTitle); 
    void addCoauthor(string paperTitle, string coauthorFirstName,string coauthorLastName, string coauthorInstitution); 
    void removeCoauthor (string coauthorFirstName, string coauthorLastName); 
    void showAllPapers(); 
    void showCoauthor(string coauthorFirstName, string coauthorLastName); 
    void showJournal(string journalTitle); 

private: 
    CDoublyLinkedList<Paper> papers; 
}; 

爲了舉辦論文,我實施了一個循環雙向鏈表課程(正如我的教練所說)。這裏是CDoublyLinkedList.cpp

// CDoublyLinkedList.cpp 

#include <cstdlib> 
#include <iostream> 

template <class T> class CDoublyLinkedList 
{ 
private: 
    struct Node 
    { 
     T data; 
     Node* prev,*next; 
     Node(const Node& other) 
     { 
      other.data = data; 
      other.prev = prev; 
      other.next = next; 
     } 

     Node(T data) 
     { 
      this->data = data; 
      prev = NULL; 
      next = NULL; 
     } 
    }; 

    Node* head; 
    int listSize; 

public: 
    CDoublyLinkedList() 
    { 
     head = NULL; 
     listSize = 0; 
    } 

    ~CDoublyLinkedList() 
    { 
     std::cout<<"CDoublyLinked List's destructor is called."<<std::endl; 
     Node* cur = head; 

     for(int ctr = 0;ctr < listSize ; ctr++) 
     { 
      head = cur->next; 
      delete cur; 
      cur = head; 
     } 
    } 

    void addToBeginning(T data) 
    { 
     Node* newNode = new Node(data); 
     std::cout<<"inside add to beginning"<<std::endl; 

     if(listSize == 0) 
     { 
      newNode->next = NULL; 
      newNode->prev = NULL; 
      head = newNode; 
      listSize++; 
      return; 
     } 
     if(listSize == 1) 
     { 
      newNode->prev = head; 
      newNode->next = head; 
      head->prev = newNode; 
      head->next = newNode; 
      head = newNode; 
      listSize++; 
      return; 
     } 

     newNode->next = head; 
     newNode->prev = head->prev; 
     head->prev->next = newNode; 
     head->prev = newNode; 
     head = newNode; 
     listSize++; 
    } 

    void addToEnd(T data) 
    { 
     Node* newNode = new Node(data); 

     //newNode->data = data; 
     if(listSize == 0) 
     { 
      newNode->next = NULL; 
      newNode->prev = NULL; 
      head = newNode; 
      listSize++; 
      return; 
     } 
     if(listSize == 1) 
     { 
      newNode->next = head; 
      newNode->prev = head; 
      head->next = newNode; 
      head->prev = newNode; 
      listSize++; 
      return; 
     } 

     newNode->next = head; 
     newNode->prev = head->prev; 
     head->prev->next = newNode; 
     head->prev = newNode; 
     listSize++; 
    } 

    void add(T data) 
    { 
     std::cout<<"Inside CDoublyLinkedList add."<<std::endl; 
     if(listSize == 0) 
     { 
      addToBeginning(data); 
      std::cout<<"After adding to the beginning"<<std::endl; 
     } 
    else 
     addToEnd(data); 
    } 

    void clearList() 
    { 
     Node* cur = head; 
     for(int ctr = 0;ctr < listSize ; ctr++) 
     { 
      head = cur->next; 
      delete cur; 
      cur = head; 
     } 

     listSize = 0; 
     head = NULL; 
    } 
}; 

這是LinkedList.cpp。由於我不會向列表中添加或刪除任何共同作者,因此我不在這裏編寫添加和刪除方法。 LinkedList.cpp

// LinkedList.cpp 

#include <iostream> 
#include <cstdlib> 

template <class T> class LinkedList 
{ 
private: 
    struct Node 
    { 
     T data; 
     Node *next; 
     Node(const Node& other) 
     { 
      other.data = data; 
      other.next = next; 
     } 
     Node(T data) 
     { 
      this->data = data; 
      next = NULL; 
     } 
    }; 

    Node *header; 
    int listSize; 

public: 
    LinkedList() 
    { 
     std::cout<<"LinkedList's constructor is called."<<std::endl; 
     header = NULL; 
     listSize = 0; 
    } 
    ~LinkedList() 
    { 
     std::cout<<"Linked List destructor is called"<<std::endl; 
     Node* temp; 
     while(header) 
     { 
      temp = header; 
      header = header -> next; 
      delete temp; 
     } 
    } 

而且我實現PaperRepository類的add方法的是在這裏: PaperRepository.cpp

// PaperRepository.cpp 

#include <cstdlib> 
#include "PaperRepository.h" 
#include <iostream> 

PaperRepository::PaperRepository() 
{ 
} 

PaperRepository::~PaperRepository() 
{ 
    papers.clearList(); 
} 

void PaperRepository::addPaper(string paperTitle, string journalTitle,int 
publicationYear) 
{ 
    std::cout<<"add paper is called."<<std::endl; 
    Paper newPaper(paperTitle,journalTitle,publicationYear); 
    std::cout<<"new paper is created."<<std::endl; 
    std::cout<<"before adding paper."<<std::endl; 
    papers.add(newPaper); 
    std::cout<<"after adding paper."<<std::endl; 
} 

我沒有添加其他的方法,因爲我的問題在add方法開始最後,我的論文和CoAuthor課程的重要部分。 Paper.cpp

// Paper.cpp 

#include <string> 
#include <iostream> 
#include "LinkedList.cpp" 
#include "CoAuthor.cpp" 

using std::string; 

class Paper 
{ 
private: 
    string title; 
    string journal; 
    int year; 
    LinkedList<CoAuthor> coAuthors; 

public: 
    Paper() 
    { 
     title = ""; 
     journal = ""; 
     year = 0; 
    } 

    Paper(string title, string journal, int year) 
    { 
     this->title = title; 
     this->journal = journal; 
     this->year = year; 
    } 

    ~Paper() 
    { 
     coAuthors.clearList(); 
    } 
}; 

而且CoAuthor.cpp

// CoAuthor.cpp 

#include <iostream> 
#include <string> 

using std::string; 

class CoAuthor 
{ 
private: 
    string name,lastName,institution; 

public: 
    CoAuthor(string name,string lastName, string institution) 
    { 
     this->name = name; 
     this->lastName = lastName; 
     this->institution = institution; 
    } 

    CoAuthor() 
    { 
     name = ""; 
     lastName = ""; 
     institution = ""; 
    } 
}; 

這是我目前正在測試該文件。 main.cpp中

// main.cpp 

#include "PaperRepository.h" 
#include <iostream> 
#include <string> 

int main() 
{ 
    PaperRepository myRep; 
    myRep.addPaper("MyTitle","Journal",1950); 
    std::cout<<"End of main..."<<std::endl; 

    return 0; 
} 

當運行該程序,我看到在當時CDoublyLinkedList.cpp命令文件的添加方法被執行被調用並「節點newNode =新節點(數據)」,該鏈表類'析構函數被調用。這對我來說很奇怪。而且,LinkedList類的析構函數總共被調用了5次。我將數據添加到循環雙向鏈表類,它調用另一個鏈表類的析構函數。對不起,這有點長,但我不能自己解釋。下面是這個文件的main.cpp輸出:

>add paper is called. 
> *LinkedList's constrctor is called. 
> *new paper is created. 
> before adding paper 
> Inside Doubly Linked List's add 
> LinkedList's constructor is called. 
> LinkedList's destructor is called. 
> inside addToBeginning. 
> LinkedList's destructor is called. 
> After addToBeginning method 
> LinkedList's destructor is called. 
> after adding paper 
> LinkedList's destructor is called. 
> End of main... 
> Linked List's destrutor is called. 
> CDoublyLinkedList's destructor is called. 
+3

你應該將你的問題減少到*最小*可編譯和可驗證的例子。此外,將輸出複製到問題中,而不是鏈接圖像。 – user2079303

+0

我添加了輸出到最後,但我無法將它最小化,因爲所有這些類一起工作。 –

+0

你的類沒有拷貝構造函數。 –

回答

2

您添加值到您的鏈表,不是指針。首先,在堆棧上實例化(例如)一個新的Paper對象。然後,你將它鏈接到鏈表,通過值來傳遞對象,從而複製對象。然後函數作用域結束,並且本地Paper對象被銷燬。

您還有各種其他類型的拼寫錯誤和基本問題。例如:

struct Node{ 
    T data; 
    Node *next; 
    Node(const Node& other){ 
     other.data = data; 
     other.next = next; 
    } 
... 
} 

甚至不應該編譯。它應該是一個複製構造函數,它將成員設置爲由other輸入參數提供的值,而不是其他方式。那個參數是const,所以你不能修改它,這就是它不應該編譯的原因。

總的來說,我建議與你的老師討論一下你的代碼。

+0

紙張也包含LinkedList作爲屬性。因此,在破壞論文時,LinkedList-Attribute的析構函數被調用。另外'void add(T data)'按值複製而不是通過引用複製,因此臨時對象被創建和銷燬。最好把它改成void add(const T&data)'。 –

+0

哦,是的,你是對的。通過傳遞值,破壞的數量減少。我希望我會找出其餘的。謝謝。 –

+0

@Oğuzhan:實際上,通過值**增加**的副本數量,因此也是析構函數的數量。按引用傳遞會減少副本數量。在你學習的時候,這是一個微型優化。唯一的情況是,如果你需要定義一個拷貝構造函數,這個拷貝構造函數不能通過值來引用它的參數(雞和雞蛋的問題 - 它必須自己調用)。 – MSalters