C ++意外的析构函数调用

奥古兹·汗(Oguz Khan)

我有关于C ++中数据结构的作业,但是遇到了一个奇怪的问题。抱歉,标题有点没用。首先,对于家庭作业,我们提供了一个PaperRepository类的头文件来实现。此类通过圆形双向链表保存论文信息。每篇论文都有标题,发表论文的期刊,发表年份以及由另一个链接列表类(排序的链接列表)保存的共同作者列表,这是PaperRepository.h文件

// 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。由于我没有在列表中添加或删除任何共同作者,因此我不在此处编写add和remove方法。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方法。最后,我的Paper和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文件的add方法中的命令并执行“ Node newNode = new Node(data)”时,LinkedList类的析构函数被调用。这对我来说很奇怪,而且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.
彼德

您正在将值添加到链接列表,而不是指针。首先,您在堆栈上实例化(例如)一个新的Paper对象。然后,将add()其传递给链接列表,并按值传递对象,该对象将复制对象。然后,函数作用域结束,并且本地Paper对象被销毁。

您还会在类中遇到其他各种错别字和基本问题。例如:

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

那甚至不应该编译。它应该是一个复制构造函数,它将成员设置为other输入参数提供的值,而不是相反。该参数const使您无法修改它,这就是为什么它不应该编译的原因。

通常,我建议与您的讲师进行简短的讨论,以讨论您的代码。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章