From 2d4a07579ef2200ee9f372546ecb77e963a0253e Mon Sep 17 00:00:00 2001 From: gaoyuankan Date: Fri, 28 Feb 2025 18:00:39 +0800 Subject: [PATCH] Finish hw02 --- .gitignore | 1 + main.cpp | 83 +++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 62 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 9ed92a0..8d87ec4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +tags build GNUmakefile diff --git a/main.cpp b/main.cpp index dc25c6b..e7ed251 100644 --- a/main.cpp +++ b/main.cpp @@ -1,33 +1,38 @@ /* 基于智能指针实现双向链表 */ #include -#include +#include // For three smart pointers +#include // It's a invaluable thing -struct Node { +// Actually, we need public inherit +struct Node : std::enable_shared_from_this { + int value; // 这两个指针会造成什么问题?请修复 + // Obviously, it will cause cycle reference std::shared_ptr next; - std::shared_ptr prev; + std::weak_ptr prev; // 如果能改成 unique_ptr 就更好了! - - int value; + // We can do this from another branch. // 这个构造函数有什么可以改进的? - Node(int val) { - value = val; + // Explicit and Initializer list + explicit Node(int val) : value(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 (next) + node->prev = shared_from_this(); + if(next) next->prev = node; + next = node; } void erase() { - if (prev) - prev->next = next; + if (prev.lock()) + prev.lock()->next = next; if (next) next->prev = prev; } @@ -43,17 +48,44 @@ struct List { List() = default; List(List const &other) { - printf("List 被拷贝!\n"); - head = other.head; // 这是浅拷贝! + printf("List copy constructor!\n"); + /* + *head = other.head; // 这是浅拷贝! + */ // 请实现拷贝构造函数为 **深拷贝** + auto origin_head = other.head; + if(!origin_head) + return; + + auto current_head = std::make_shared(origin_head->value); + auto result = current_head; + origin_head = origin_head->next; + while(origin_head){ + //while(origin_head.get()){ + current_head->insert(origin_head->value); + origin_head = origin_head->next; + current_head = current_head->next; + } + // Inside constructor, there is no content before, so it's redundant. + // You can see the content of front() + assert(!front()); + printf("front() == %p\n", front()); + for (auto cur = front(); cur; ) { + auto tmp = cur; + cur = cur->next.get(); + delete tmp; + } + head = result; } + // From this source file context, there is no lvalue assignment copy action. List &operator=(List const &) = delete; // 为什么删除拷贝赋值函数也不出错? + // Move sementics List(List &&) = default; List &operator=(List &&) = default; - Node *front() const { + Node* front() const { return head.get(); } @@ -72,6 +104,7 @@ struct List { } Node *at(size_t index) const { + // auto is Node* auto curr = front(); for (size_t i = 0; i < index; i++) { curr = curr->next.get(); @@ -80,10 +113,10 @@ struct List { } }; -void print(List lst) { // 有什么值得改进的? +void print(const List& lst) { // 有什么值得改进的? printf("["); - for (auto curr = lst.front(); curr; curr = curr->next.get()) { - printf(" %d", curr->value); + for (auto cur = lst.front(); cur; cur = cur->next.get()) { + printf(" %d", cur->value); } printf(" ]\n"); } @@ -98,18 +131,24 @@ int main() { a.push_front(9); a.push_front(4); a.push_front(1); + a.push_front(9); - print(a); // [ 1 4 9 2 8 5 7 ] + print(a); // [9 1 4 9 2 8 5 7] + a.pop_front(); + print(a); // [1 4 9 2 8 5 7] + a.at(2)->erase(); - print(a); // [ 1 4 2 8 5 7 ] List b = a; a.at(3)->erase(); - print(a); // [ 1 4 2 5 7 ] + + a.at(3)->insert(10); + print(a); // [ 1 4 2 5 10 7 ] + print(b); // [ 1 4 2 8 5 7 ] b = {};