diff --git a/main.cpp b/main.cpp index dc25c6b..3c36a76 100644 --- a/main.cpp +++ b/main.cpp @@ -4,51 +4,64 @@ struct Node { // 这两个指针会造成什么问题?请修复 - std::shared_ptr next; - std::shared_ptr prev; + //可能产生循环引用导致内存泄漏 + std::unique_ptr next; + Node* prev; // 如果能改成 unique_ptr 就更好了! int value; // 这个构造函数有什么可以改进的? - Node(int val) { - value = val; - } + //使用初始化列表构造 减少一次拷贝 并把prev内存清空,避免空悬指针 + explicit Node(int val): value(val),prev(nullptr){} void insert(int val) { - auto node = std::make_shared(val); - node->next = next; + auto node = std::make_unique(val); + node->next = std::move(next); node->prev = prev; if (prev) - prev->next = node; + prev->next = std::move(node); if (next) - next->prev = node; + next->prev = node.get(); } void erase() { if (prev) - prev->next = next; + prev->next = std::move(next); if (next) next->prev = prev; } ~Node() { printf("~Node()\n"); // 应输出多少次?为什么少了? + // shared_ptr会导致循环引用,因此List被解析以后,Node不会被释放。 } }; struct List { - std::shared_ptr head; + std::unique_ptr head; List() = default; List(List const &other) { printf("List 被拷贝!\n"); - head = other.head; // 这是浅拷贝! + //head = other.head; // 这是浅拷贝! // 请实现拷贝构造函数为 **深拷贝** + if (other.head) { + head = std::make_unique(other.head->value); + Node* curr = head.get(); + Node* currOther = other.head.get(); + while (currOther->next) { + curr->next=std::make_unique(currOther->next->value); + curr->next->prev = curr; + curr = curr->next.get(); + currOther = currOther->next.get(); + } + } } List &operator=(List const &) = delete; // 为什么删除拷贝赋值函数也不出错? + //因为定义了移动赋值函数,编译器在无拷贝赋值的情况下会尝试移动赋值 List(List &&) = default; List &operator=(List &&) = default; @@ -59,16 +72,17 @@ struct List { int pop_front() { int ret = head->value; - head = head->next; + 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; + auto node = std::make_unique(value); + node->next = std::move(head); + if (node->next) { + node->next->prev = node.get(); + } + head = std::move(node); } Node *at(size_t index) const { @@ -80,7 +94,8 @@ struct List { } }; -void print(List lst) { // 有什么值得改进的? +void print(List const &lst) { // 有什么值得改进的? + //改为传const引用,因为打印不涉及到对象的控制权,也无需修改对象属性 printf("["); for (auto curr = lst.front(); curr; curr = curr->next.get()) { printf(" %d", curr->value);