2015-05-26 59 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