From 57298121c463d28dbbdd87f68cbf5496e535bfff Mon Sep 17 00:00:00 2001 From: "N.O.Atomusk" Date: Fri, 18 Mar 2022 17:55:23 +0800 Subject: [PATCH] :pencil:unique_ptr & normal ptr --- main.cpp | 145 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 41 deletions(-) diff --git a/main.cpp b/main.cpp index dc25c6b..0fe5465 100644 --- a/main.cpp +++ b/main.cpp @@ -2,76 +2,101 @@ #include #include -struct Node { +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; + Node(T val) : next(nullptr), prev(nullptr), value(val) + {} + Node(T val, std::unique_ptr> next, Node* prev) + : next(std::move(next)), prev(prev), value(val) + { + if (next) + next->prev = this; } - void insert(int val) { - auto node = std::make_shared(val); - node->next = next; - node->prev = prev; - if (prev) - prev->next = node; - if (next) - next->prev = node; + void insert(T val) + { + prev->next = std::make_unique>(val, std::move(next), prev); } - void erase() { - if (prev) - prev->next = next; + void erase() + { if (next) next->prev = prev; + if (prev) + prev->next = std::move(next); } - ~Node() { + ~Node() + { printf("~Node()\n"); // 应输出多少次?为什么少了? } }; -struct List { - std::shared_ptr head; +template +struct List +{ + std::unique_ptr> head; List() = default; - List(List const &other) { + List(List const& other) + { printf("List 被拷贝!\n"); - head = other.head; // 这是浅拷贝! + // head = other.head; // 这是浅拷贝! // 请实现拷贝构造函数为 **深拷贝** + auto* other_ptr = other.head.get(); + auto* this_ptr = head.get(); + while (other_ptr) { + if (this_ptr) { + this_ptr->next = std::make_unique>(other_ptr->value, nullptr, this_ptr); + this_ptr = this_ptr->next.get(); + } + else { + head = std::make_unique>(other_ptr->value, nullptr, nullptr); + this_ptr = head.get(); + } + other_ptr = other_ptr->next.get(); + } } - List &operator=(List const &) = delete; // 为什么删除拷贝赋值函数也不出错? + List& operator=(List const&) = delete; // 为什么删除拷贝赋值函数也不出错? - List(List &&) = default; - List &operator=(List &&) = default; + 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() + { + 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) + { + auto node = std::make_unique>(value); + if (head) { + node->next = std::move(head); + node->next->prev = node.get(); + } + 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++) { curr = curr->next.get(); @@ -80,16 +105,31 @@ struct List { } }; -void print(List lst) { // 有什么值得改进的? +template +void print(const List& lst); + +template<> +void print(const List& lst) +{ // 有什么值得改进的? printf("["); for (auto curr = lst.front(); curr; curr = curr->next.get()) { printf(" %d", curr->value); } printf(" ]\n"); } +template<> +void print(const List& lst) +{ // 有什么值得改进的? + printf("["); + for (auto curr = lst.front(); curr; curr = curr->next.get()) { + printf(" %c", curr->value); + } + printf(" ]\n"); +} -int main() { - List a; +int main() +{ + List a; a.push_front(7); a.push_front(5); @@ -105,15 +145,38 @@ int main() { print(a); // [ 1 4 2 8 5 7 ] - List b = a; + List b = a; a.at(3)->erase(); print(a); // [ 1 4 2 5 7 ] print(b); // [ 1 4 2 8 5 7 ] - b = {}; a = {}; + List ac; + + ac.push_front('7'); + ac.push_front('5'); + ac.push_front('8'); + ac.push_front('2'); + ac.push_front('9'); + ac.push_front('4'); + ac.push_front('1'); + + print(ac); // [ 1 4 9 2 8 5 7 ] + + ac.at(2)->erase(); + + print(ac); // [ 1 4 2 8 5 7 ] + + List bc = ac; + + ac.at(3)->erase(); + + print(ac); // [ 1 4 2 5 7 ] + print(bc); // [ 1 4 2 8 5 7 ] + bc = {}; + ac = {}; return 0; }