C ++ непреднамеренные вызовы деструкторов

У меня есть домашняя работа о структурах данных в 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. Поскольку я не добавляю и не удаляю соавторов в список, я не пишу здесь методы добавления и удаления.
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;
}
}

И моя реализация метода add класса PaperRepository находится здесь:
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 и выполняется «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.

-1

Решение

Вы добавляете значения в свои связанные списки, а не указатели. Сначала вы создаете (например) новый объект Paper в стеке. Затем вы add() это к связанному списку, передавая объект по значению, который копирует объект. Затем область действия функции заканчивается, и локальный объект Paper уничтожается.

У вас также есть различные другие опечатки и основные проблемы с классами. Например:

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

Это не должно даже компилироваться. Предполагается, что это конструктор копирования, который устанавливает для членов значения, предоставленные other входной параметр, а не наоборот. Этот параметр const так что вы не можете изменить его, поэтому он не должен компилироваться.

В общем, я рекомендую короткую сессию с вашим инструктором, чтобы обсудить ваш код.

2

Другие решения


По вопросам рекламы [email protected]