

二つの連結リストを結合させ（一つの連結リストをもう片方の連結リストにつなげる）、その結合したリストを表示させるプログラムを作りたいです。

やりたいことはできているのですが、最後、正常に終わりません（0を返さない）。どうやら、appendメソッドがうまくいっていないようです。デバッグしたところsetPrevメソッドで永遠にループしてしまっているようです。

しかし、これが本当に問題なのか、そうだとしたら、どう解決したらいいかが分かりません。結合した連結リストをmain.cppで表示したところ、つながってはいるみたいです。

**main.cpp**

[code]

    #include <iostream>
    #include "TextClass.h"
    
    using namespace std;
    
    int main() {
        const int APPEND1 = 6;
        const int APPEND2 = 7;
        int counter = 0;
        char appendVals[APPEND1 + APPEND2] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'};
    
        TextClass first;
        for (int i = 0; i < APPEND1; i++)
        {
            first.addTail(appendVals[counter]);
            counter++;
        }
        TextClass second;
        for (int i = 0; i < APPEND2; i++)
        {
            second.addTail(appendVals[counter]);
            counter++;
        }
    
        std::cout << "First list is " << first.displayList() << std::endl;
        std::cout << "Second list is " << second.displayList() << std::endl;
    
        first.append(second);
        std::cout << "First should now be a b c d e f g h i j k l m" << std::endl;
        std::cout << " and it actually is " << first.displayList() << std::endl;
    
        std::cout << "Done appending a list\n" << std::endl;
    
    
        return 0;
    }
    
[/code]

**TextClass.cpp**

[code]

    #include "TextClass.h"
    #include <sstream>
    //constructor
    Link::Link(char letter, Link* next, Link* prev)
    {
        value = letter;
        this->next = next;
        this->prev = prev;
    }
    
    //destructor
    Link::~Link(){}
    
    //return the value in the link
    char Link::getValue(){return value;}
    
    //set a new next address
    void Link::setNext(Link* next){this->next = next;}
    
    //set a new previous address
    void Link::setPrev(Link* prev){this->prev = prev;}
    
    // return the next address
    Link* Link::getNext(){return this->next;}
    
    // return the previous address
    Link* Link::getPrev(){return this->prev;}
    
    
    //constructor
    TextClass::TextClass()
    {
        //head and tail are set to nullptr
        head = nullptr;
        tail = nullptr;
    }
    
    //destructor
    TextClass::~TextClass()
    {
        //call removeHead until head = nullptr;
        while(head != nullptr)
        {
            removeHead();
        }
    }
    
    
    //add value at tail
    void TextClass::addTail(char letter)
    {
        //if head == nullptr
        if(tail == nullptr)
        {
            //head and tail = new link
            head = tail = new Link(letter);
        }
            //else
        else
        {
            //create new link and insert it at tail
            Link* temp = new Link(letter, nullptr, tail);
            tail->setNext(temp);
            //change tail
            tail = temp;
        }
    }
    
    
    //return the contents of list
    string TextClass::displayList()
    {
    
        //create a variable that stores contents for string and stringstream
        string output;
        std::stringstream ss;
        //create a link that walks down the list and it starts from head
        Link* temp = head;
        //while the link != nullptr
        while(temp != nullptr)
        {
            //copy the value in the link to stringstream
            ss << temp->getValue() << " ";
            //move the link forward
            temp = temp->getNext();
        }
    
        //copy the value in stringstream to string
        output = ss.str();
    
        //return the string
        return output;
    }
    
    //connects two lists
    void TextClass::append(TextClass otherList)
    {
        //create a link that stores the head of otherList
        Link* temp = otherList.head;
    
        //connect two links
        //tail next should point to head of otherLink
        while(temp != nullptr)
        {
            addTail(temp->getValue());
            temp = temp->getNext();
        }
    
    }
    
    //remove head
    void TextClass::removeHead()
    {
        //save the link at head to delete later
        Link* temp = head;
        //update head
        head = head->getNext();
        //if head is null after update
        if(head == nullptr)
        {
            //tail = nullptr
            tail = nullptr;
        }
            //else update prev of new link
        else
        {
            head->setPrev(nullptr);
        }
        //now delete the old link
        delete temp;
    }
    
[/code]

**TextClass.h**

[code]

    #include <iostream>
    
    
    using std::string;
    
    class Link {
    private:
        char value; //stores chat type value
        Link* next; //stores the address of next link
        Link* prev; //stores the address of previous link
    
    public:
        Link(char letter, Link* next = nullptr, Link* prev = nullptr); //constructor
        ~Link(); //destructor
        char getValue(); //return the value in the link
        void setNext(Link* next); //set a new next address
        void setPrev(Link* prev); //set a new previous address
        Link* getNext(); // return the next address
        Link* getPrev(); // return the previous address
    };
    
    
    class TextClass {
    private:
        Link* head; //track the head link of queue
        Link* tail; //track the tail link of queue
    public:
        TextClass(); //constructor
        ~TextClass(); //destructor
    
        void addTail(char letter); //add value at tail
        string displayList(); // return the contents of list
        void append(TextClass otherList); //connects two lists
        void removeHead(); //remove head
    };
    
[/code]


CC BY-SA 4.0
2021-10-15T03:28:57.110
83103
2021-10-15T05:39:41.400
2021-10-15T05:39:41.400
3060
45177
question
c++
二つの連結リストを結合させ、そのリストを表示させるプログラムです。やりたいことはできているのですが、最後、正常に終わりません。


何をもって「正常」とするのか一言も書かれていませんので、どう直せば「あなたにとっての正解」なのか読者にはわかりません。読者の推定はあなたの期待通りとは限らないので・・・

まあとりあえずこの問題に関しては次の修正でいけそうな気がします。

誤： `void TextClass::append(TextClass otherList)`  
正： `void TextClass::append(TextClass const& otherList)`  
（ `TextClass.h` と `TextClass.cpp` の両方を修正）

誤だと `append()` の呼び出しの際に引数である `otherList`
の複写（コピーコンストラクト）と破棄（デストラクト）が行われます。が、提示ソースには `TextClass`
のコピーコンストラクタが提供されていません。そのため期待通りの動きをしていないのでしょう（何が正解かわからないので推測）

正だと複写が発生しないので破棄も発生せず、よって問題ないです。

ンでこの辺を詳しく解説すると結構長くなりそうです。ディープコピーとシャローコピーとかうんぬん。興味があれば別の質問を挙げてください。


CC BY-SA 4.0
2021-10-15T04:52:31.283
83105
2021-10-15T04:52:31.283
8589
83103
answer