diff --git a/main.cpp b/main.cpp index dc25c6b..82a3ef6 100644 --- a/main.cpp +++ b/main.cpp @@ -1,39 +1,40 @@ /* 基于智能指针实现双向链表 */ #include #include +#include struct Node { - // 这两个指针会造成什么问题?请修复 + // 这两个指针会造成什么问题?请修复 (使用weak_ptr避免循环引用, 这里其实是要把prev变成weak_ptr, 因为要保证上一个节点释放时它的next不再持有对它的引用) std::shared_ptr next; - std::shared_ptr prev; + std::weak_ptr prev; // 如果能改成 unique_ptr 就更好了! int value; - // 这个构造函数有什么可以改进的? - Node(int val) { - value = val; + // 这个构造函数有什么可以改进的?(使用初始化表达式) + Node(int val): value(val) { + } void insert(int val) { auto node = std::make_shared(val); node->next = next; node->prev = prev; - if (prev) - prev->next = node; + if (!prev.expired()) + prev.lock()->next = node; if (next) next->prev = node; } void erase() { - if (prev) - prev->next = next; + if (!prev.expired()) + prev.lock()->next = next; if (next) next->prev = prev; } ~Node() { - printf("~Node()\n"); // 应输出多少次?为什么少了? + printf("~Node()\n"); // 应输出多少次?为什么少了? (反正就是少输出啦, 因为产生了循环引用) } }; @@ -44,11 +45,25 @@ struct List { List(List const &other) { printf("List 被拷贝!\n"); - head = other.head; // 这是浅拷贝! - // 请实现拷贝构造函数为 **深拷贝** + // head = other.head; // 这是浅拷贝! + // 请实现拷贝构造函数为 **深拷贝** (深拷贝的实现如下) + auto curr = other.front(); + std::shared_ptr prev; + while(curr) { + auto newNode = std::make_shared(curr->value); + if (!head.get()) { + head = newNode; + } + if (prev) { + newNode->prev = prev; + prev->next = newNode; + } + prev = newNode; + curr = curr->next.get(); + } } - List &operator=(List const &) = delete; // 为什么删除拷贝赋值函数也不出错? + List &operator=(List const &) = delete; // 为什么删除拷贝赋值函数也不出错? (因为实际调用的是拷贝构造函数) List(List &&) = default; List &operator=(List &&) = default; @@ -80,7 +95,7 @@ struct List { } }; -void print(List lst) { // 有什么值得改进的? +void print(const List &lst) { // 有什么值得改进的?(这里实际只对lst做了输出, 改为const &避免拷贝) printf("["); for (auto curr = lst.front(); curr; curr = curr->next.get()) { printf(" %d", curr->value); @@ -107,6 +122,8 @@ int main() { List b = a; + print(b); + a.at(3)->erase(); print(a); // [ 1 4 2 5 7 ]