c++ - 链表复制/移动语义 C++

标签 c++ c++11 linked-list copy-constructor move-constructor

所以我有下面链接列表的代码。我需要创建复制/移动构造函数和运算符。 我遇到了如何以正确的方式做到这一点的麻烦。

我知道代码并不完美,我会感谢所有提示,但我想主要关注复制/移动语义。

#include <iostream>
#include <string>
#include <stdexcept>

using namespace std;

class List {
    class Node {
        Node* next;
        string text;
        int index;
        friend class List;
      public:
        Node(const string& value, int i) : next(nullptr), index(i), text(value) {}
        friend ostream& operator<< (ostream& wy, const Node& wzl) {
            if (wzl.next) return wy << wzl.text << ", " << *wzl.next;
            else return wy << wzl.text;
        }
    };

    Node* head;

    int _size(Node* node, int size = 0) { 
        if (node == NULL) {
            return size;
        } else {
            _size(node->next, size+1);
        }
    }

    void _insert(Node* node, const string& value, int index) {
        if (node->next == NULL || node->next->index > index) {
            if (node->index == index) {
                node->text = value;
            } else {
                Node* element = new Node(value, index);
                element->next = node->next;
                node->next = element;
            }
        } else {
            _insert(node->next, value, index);
        }
    }

    string _read(Node* node, int index) {
        if (node->next != NULL && node->next->index <= index) {
            return _read(node->next, index);
        } else if (node->index == index) {
            return node->text;
        } else {
            throw invalid_argument("No such index");
        }
    }

    void _remove(Node* node, int index) {
        if (node->next != NULL && node->next->index < index) {
            _remove(node->next, index);
        } else if (node->next->index == index) {
            Node* temp;

            if (node->next->next != NULL) {
                int temp_index = node->next->next->index;
                temp = new Node(node->next->next->text, temp_index);
                if (node->next->next->next != NULL) { 
                    temp->next = node->next->next->next;
                } else {
                    temp->next = NULL;
                }
                temp->index = node->next->next->index;
            } else {
                temp = nullptr;
            }

            delete node->next;
            node->next = temp;
        } else {
            throw invalid_argument("No such index");
        }
    }

public:
    List() : head(nullptr){};
    List(const List &lst) : head(nullptr) {
        Node* tmp_lst = lst.head;
        Node* tmp_this = this->head;

        while (tmp_lst != NULL) {
            // cerr << this->head->text;
            tmp_this = new Node(tmp_lst->text, tmp_lst->index);
            tmp_this = tmp_this->next;
            tmp_lst = tmp_lst->next;
        }
    }
    List(List&& lst);
    List(initializer_list<string> lst) : List() {
        Node* tmp;
        int pos = 0;
        for (auto element : lst) {
            if (this->head != NULL){
                tmp->next = new Node(element, pos);
                tmp = tmp->next;
                pos++;
            } else {
                this->head = new Node(element, pos);
                tmp = this->head;
                pos++;
            }
        }
    };
    List& operator= (const List& lst) {
        if (this != &lst) {
            delete this->head;

            this->head = nullptr;

            Node* tmp_lst = lst.head;
            Node* tmp_this = this->head;

            while (tmp_lst != NULL) {
                tmp_this = new Node(tmp_lst->text, tmp_lst->index);
                tmp_this = tmp_this->next;
                tmp_lst = tmp_lst->next;
            }
        }
        return *this;
    }
    List& operator= (List&& lst);
    ~List(){
        delete head;    
    };

    void insert(const string& value, int pos) {
        if (pos < 0) {
            throw invalid_argument("Position cant be negative");
        }

        if (this->head == NULL) {
            Node* new_head = new Node(value, pos);
            this->head = new_head;
        } else if (this->head->index > pos) {
            Node* new_head = new Node(value, pos);
            new_head->next = this->head;
            this->head = new_head;
        } else {
            _insert(this->head, value, pos);
        }
    }

    string read(int pos) {
        return _read(this->head, pos);
    }    

    int size() {
       return _size(this->head);
    }

    void remove(int pos) {
        return _remove(this->head, pos);
    }

public:
    friend ostream& operator<< (ostream& wy, const List& lst) {
        if (lst.head) return wy << "(" << *lst.head << ")";
        else return wy << "()";
    }
};

int main() {
    return 0;
}

最佳答案

您的 List 复制构造函数存在严重缺陷:

  • 你将 tmp_this 初始化为 this->head 的值,它是一个空指针
  • 以上并不重要,因为您在循环中做的第一件事是重新分配 tmp_this 以指向新的 Node 对象。
  • 然后您立即丢弃该指针,方法是将 tmp_this 重新分配为指向 tmp_this->next,这是一个空指针。
  • 并且您没有将任何内容链接到列表中。

一个工作函数看起来像

List(const List &lst) : head(nullptr) {
    Node* tmp_lst = lst.head;
    Node** tmp_current = &head;

    while (tmp_lst != NULL) {
        Node* tmp_this = new Node(tmp_lst->text, tmp_lst->index);

        // Would prefer to use the copy-constructor here too, instead of the above
        // Node* tmp_this = new Node(tmp_lst);

        // This links the new node into the end of the list
        *tmp_current = tmp_this
        tmp_current = &tmp_this->next;

        tmp_lst = tmp_lst->next;
    }
}

关于c++ - 链表复制/移动语义 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36282346/

相关文章:

c++ - 简单可靠的 UDP C++ 库

c++ - C++中如何控制cin到cout的流程

c++ - 为什么没有找到 operator<< 重载?

C++/OpenGL : Texture to pixmap example - narrowing conversion error

algorithm - 混合数据结构对效率的好处

c++ - 如何在 Windows 中比较可能的替代文件名?

c++ - OS X Eclipse C++ 启动失败 - 找不到二进制文件

c++ - 以模板化函数作为参数的 STL 算法

C - 使用链表的自适应动态内存?

java - 从 LinkedList 中删除特定元素....?