diff --git a/main.cpp b/main.cpp index dc25c6b..25b3f60 100644 --- a/main.cpp +++ b/main.cpp @@ -1,77 +1,72 @@ /* 基于智能指针实现双向链表 */ -#include +#include #include +#include -struct Node { - // 这两个指针会造成什么问题?请修复 - std::shared_ptr next; - std::shared_ptr prev; - // 如果能改成 unique_ptr 就更好了! +template struct Node { + std::unique_ptr next; + Node *prev; + Tp value; - int value; - - // 这个构造函数有什么可以改进的? - 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 (next) - next->prev = node; - } + Node(Tp val): value(val) {} + ~Node() { std::clog << "~Node(" << value << ")\n"; } + void insert(Tp val) { value = val; } void erase() { - if (prev) - prev->next = next; - if (next) - next->prev = prev; - } - - ~Node() { - printf("~Node()\n"); // 应输出多少次?为什么少了? + if (next) next->prev = prev; + if (prev) prev->next = std::move(next); } }; -struct List { - std::shared_ptr head; +template > struct List { + std::unique_ptr> head; List() = default; - - List(List const &other) { - printf("List 被拷贝!\n"); - head = other.head; // 这是浅拷贝! - // 请实现拷贝构造函数为 **深拷贝** + List(Init const &range) { + if (range.begin() == range.end()) return; + Node *tail; + auto it = range.begin(); + head = std::make_unique>(*it); + for (++it, tail = head.get(); it != range.end(); ++it) { + tail->next = std::make_unique>(*it); + tail->next->prev = tail; + tail = tail->next.get(); + } } - - List &operator=(List const &) = delete; // 为什么删除拷贝赋值函数也不出错? - + List &operator=(List const &) = delete; // 为什么删除拷贝赋值函数也不出错? + // 因为编译器会用“解构函数+拷贝构造”代替拷贝赋值。 List(List &&) = default; List &operator=(List &&) = default; - Node *front() const { - return head.get(); - } - + struct iterator { + Node *node; + iterator(Node *p): node(p) {} + + Tp operator*() { return node->value; } + iterator operator++() { return node = node->next.get(); } + iterator operator--() { return node = node->prev; } + bool operator==(iterator const &other) { return node == other.node; } + bool operator!=(iterator const &other) { return node != other.node; } + }; + iterator begin() const { return iterator(head.get()); } + iterator end() const { return iterator(nullptr); } + + Node *front() const { return head.get(); } + bool empty() const { return !(head); } int pop_front() { + if (head == nullptr) return 0x114154; 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; + auto node = new Node(value); if (head) head->prev = node; - head = node; + node->next = std::move(head); + head = std::unique_ptr>(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,40 +75,24 @@ struct List { } }; -void print(List lst) { // 有什么值得改进的? - printf("["); - for (auto curr = lst.front(); curr; curr = curr->next.get()) { - printf(" %d", curr->value); - } - printf(" ]\n"); +template +std::ostream &operator<<(std::ostream &os, List const &l) { + for (os << '['; Tp x : l) os << x << ", "; + os << (l.empty() ? "]" : "\b\b]"); + return os; } int main() { - List a; - - a.push_front(7); - a.push_front(5); - a.push_front(8); - a.push_front(2); - a.push_front(9); - a.push_front(4); - a.push_front(1); - +#define print(l) std::cout << l << '\n'; + List a = {1, 4, 9, 2, 8, 5, 7}; print(a); // [ 1 4 9 2 8 5 7 ] - a.at(2)->erase(); - 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 = {}; - return 0; }