diff --git a/main.cpp b/main.cpp index dc25c6b..d002a97 100644 --- a/main.cpp +++ b/main.cpp @@ -2,94 +2,116 @@ #include #include +template struct Node { // 这两个指针会造成什么问题?请修复 - std::shared_ptr next; - std::shared_ptr prev; + // 会造成循环引用 + std::unique_ptr> next; + Node *prev; // 如果能改成 unique_ptr 就更好了! - int value; + T value; // 这个构造函数有什么可以改进的? - Node(int val) { - value = val; - } + // 改为 member list initilization 并初始化所有成员 + Node(T _val): next{nullptr}, prev{nullptr}, value{_val} {} - void insert(int val) { - auto node = std::make_shared(val); - node->next = next; - node->prev = prev; - if (prev) - prev->next = node; + // 头插法 + void insert(T val) { + std::unique_ptr> node = std::make_unique>(val); if (next) - next->prev = node; + next->prev = node.get(); + node->next = std::move(next); + node->prev = this; + next = std::move(node); } + // 将前后两个 Node 链接,本身 Node 没有 unique_ptr 管理所有权,析构 void erase() { - if (prev) - prev->next = next; - if (next) + if (next) next->prev = prev; + if (prev != nullptr) + prev->next = std::move(next); } ~Node() { - printf("~Node()\n"); // 应输出多少次?为什么少了? + printf("~Node()\n"); // 应输出多少次?为什么少了?:之前有循环引用,导致内存泄露 } }; +template struct List { - std::shared_ptr head; + std::unique_ptr> head; List() = default; - List(List const &other) { + List(List const &other) { printf("List 被拷贝!\n"); - head = other.head; // 这是浅拷贝! + Node *tmp; // 请实现拷贝构造函数为 **深拷贝** + for (Node* curr = other.front(); curr != nullptr; curr = curr->next.get()) { + if(head) { + tmp->next = std::make_unique>(curr->value); + tmp = tmp->next.get(); + } else { + head = std::make_unique>(curr->value); + tmp = head.get(); + } + } } List &operator=(List const &) = delete; // 为什么删除拷贝赋值函数也不出错? + // 因为在拷贝赋值的 call site 可以变成 拷贝构造(构造出一个右值) + 移动赋值 的调用 List(List &&) = default; List &operator=(List &&) = default; - Node *front() const { + Node *front() const { return head.get(); } - int pop_front() { - int ret = head->value; - head = head->next; + T pop_front() { + if (!head) { + throw std::out_of_range("pop_front()"); + } + T ret = head->value; + head = std::move(head->next); return ret; } - void push_front(int value) { - auto node = std::make_shared(value); - node->next = head; - if (head) - head->prev = node; - head = node; + void push_front(T value) { + if(!head) { + head = std::make_unique>(value); + } + else { + auto node = std::make_unique>(value); + head->prev = node.get(); + node->next = std::move(head); + node->prev = nullptr; + head = std::move(node); + } } - Node *at(size_t index) const { + Node *at(size_t index) const { auto curr = front(); - for (size_t i = 0; i < index; i++) { + for (size_t i = 0; curr != nullptr && i < index; i++) { curr = curr->next.get(); } return curr; } }; -void print(List lst) { // 有什么值得改进的? +template +void print(const List &lst) { // 参数类型改为 const ref printf("["); - for (auto curr = lst.front(); curr; curr = curr->next.get()) { + for (auto curr = lst.front(); curr != nullptr; curr = curr->next.get()) { printf(" %d", curr->value); } printf(" ]\n"); } int main() { - List a; + List a; a.push_front(7); a.push_front(5); @@ -105,7 +127,7 @@ int main() { print(a); // [ 1 4 2 8 5 7 ] - List b = a; + List b = a; a.at(3)->erase();