-1

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;
}

問題はメソッドの追加から始まるため、他のメソッドは追加しませんでした。最後に、Paper クラスと CoAuthor クラスの重要な部分があります。紙.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.
4

1 に答える 1

2

ポインターではなく、リンクされたリストに値を追加しています。まず、(たとえば) スタック上で新しい Paper オブジェクトをインスタンス化します。次に、add()リンクされたリストにオブジェクトを渡し、オブジェクトを値で渡します。これにより、オブジェクトがコピーされます。その後、関数スコープが終了し、ローカルの Paper オブジェクトが破棄されます。

クラスには、他にもさまざまなタイプミスや基本的な問題があります。例えば:

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

それはコンパイルさえすべきではありません。これは、メンバーをother入力パラメーターによって提供された値に設定するコピー コンストラクターであると想定されており、その逆ではありません。そのパラメーターはconst変更できないようになっているため、コンパイルしないでください。

一般に、インストラクターとの短いセッションでコードについて話し合うことをお勧めします。

于 2015-05-26T14:03:34.283 に答える