From dfe797bbe723f627e31b1b4712eb5d1487cc7462 Mon Sep 17 00:00:00 2001 From: TheNoob Date: Fri, 6 Dec 2024 14:38:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=88=91=E5=86=8D=E6=AC=A1=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- ans.cpp | 155 +++++++++++++++++++++++++++++++++++++++++++++++++ reference.cpp | 74 +++++++++++++++++++++++ 3 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 ans.cpp create mode 100644 reference.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b1d4bec..b7d5886 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,4 +6,4 @@ if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug) endif() -add_executable(main main.cpp) +add_executable(main ans.cpp) diff --git a/ans.cpp b/ans.cpp new file mode 100644 index 0000000..df188c8 --- /dev/null +++ b/ans.cpp @@ -0,0 +1,155 @@ +#include +#include + +// 节点的实现 +template +struct Node { + std::unique_ptr next; + Node* prev; + T m_val; + + // 构造函数 + explicit Node(T const& val) + : m_val(val) {} + + void erase() { + // 这里一定要注意,要先定义 next->prev = prev,否则会直接将 next 给 move 走 + if(next) + next->prev = prev; + if(prev) + prev->next = std::move(next); + // if(next) + // next->prev = prev; + } + + ~Node() { + printf("~Node()\n"); + } +}; + +template +struct List { +public: + using node_type = Node; + + // 迭代器本质上还是指针,相当于泛化的指针 + class List_Iterator { + public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = node_type; + using difference_type = std::ptrdiff_t; + using pointer = node_type*; + using reference = node_type&; + + List_Iterator(pointer ptr) + : m_ptr(ptr) {} + // 解引用操作符 + reference operator*() { return *m_ptr; } + pointer operator->() { return m_ptr; } + // 前缀自增运算符 + List_Iterator& operator++() { + m_ptr = m_ptr->next.get(); + return *this; + } + // 后缀自增运算符 + List_Iterator operator++(int) { + List_Iterator tmp = *this; + ++ (*this); + return tmp; + } + // 比较运算符 + bool operator==(List_Iterator const& other) { return m_ptr == other.m_ptr; } + bool operator!=(List_Iterator const& other) { return m_ptr != other.m_ptr; } + private: + pointer m_ptr; + }; + +public: + std::unique_ptr head; + node_type* tail; + + List() = default; + + List(List const& other) { + printf("List 被拷贝了!\n"); + head = std::make_unique(other.begin()->m_val); + tail = head.get(); + for(auto it = ++other.begin(); it != other.end(); ++ it) { + push_back(it->m_val); + } + } + + List& operator=(List const&) = delete; + + List(List &&) = default; + List& operator=(List &&) = default; + + // front + node_type* front() const { + return head.get(); + } + // pop_front + T pop_front() { + T res = head->value; + head = std::move(head->next); + return res; + } + // push_front + void push_front(T const& val) { + auto node = std::make_unique(val); + if(head) + head->prev = node.get(); + else + tail = node.get(); + node->next = std::move(head); + head = std::move(node); + } + // push_back + void push_back(T const& val) { + auto node = std::make_unique(val); + node->prev = tail; + tail->next = std::move(node); + tail = tail->next.get(); + } + // at + node_type* at(size_t index) const { + auto cur = front(); + for(size_t i = 0; i < index; i ++) { + cur = cur->next.get(); + } + return cur; + } + List_Iterator begin() const { return List_Iterator(head.get()); } + List_Iterator end() const { return List_Iterator(nullptr); } +}; + +template +void print(List const& list) { + printf("["); + for(auto cur = list.front(); cur; cur = cur->next.get()) + printf(" %f", cur->m_val); + printf(" ]\n"); +} + +int main() { + List a; + + a.push_front(7.2f); + a.push_front(5.5f); + a.push_front(8.2f); + a.push_front(2.1f); + a.push_front(9.3f); + a.push_front(4.5f); + a.push_front(1.9f); + + print(a); + a.at(2)->erase(); + print(a); + + List b = a; + a.at(3)->erase(); + + b = {}; + a = {}; + return 0; +} diff --git a/reference.cpp b/reference.cpp new file mode 100644 index 0000000..88365b5 --- /dev/null +++ b/reference.cpp @@ -0,0 +1,74 @@ +#include +#include + +template +class MyRandomAccessIterator { +public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = T; + using difference_type = std::ptrdiff_t; + using pointer = T*; + using reference = T&; + + MyRandomAccessIterator(pointer ptr) + : m_ptr(ptr) {} + + // 解引用运算符 + reference operator*() const { return *m_ptr; } + pointer operator->() const { return m_ptr; } + + // 前缀自增运算符 + MyRandomAccessIterator& operator++() { + ++ m_ptr; + return *this; + } + + // 后缀自增运算符 + MyRandomAccessIterator operator++(int) { + MyRandomAccessIterator tmp = *this; + ++(*this); + return tmp; + } + + // 随机访问运算符 + reference operator[](size_t index) const { return *(m_ptr + index); } + + // 赋值运算符 + bool operator==(MyRandomAccessIterator const& other) const { return m_ptr == other.m_ptr; } + bool operator!=(MyRandomAccessIterator const& other) const { return m_ptr != other.m_ptr; } +private: + pointer m_ptr; +}; + +template +class MyContainer { +public: + using iterator = MyRandomAccessIterator; + + void add(T const& val) { + m_data.push_back(val); + } + + iterator begin() { return iterator(m_data.data());} + iterator end() { return iterator(m_data.data() + m_data.size());} +private: + std::vector m_data; +}; + +int main() { + MyContainer container; + + container.add(1); + container.add(2); + container.add(3); + + for(auto it = container.begin(); it != container.end(); it ++) + std::cout << *it << ' '; + std::cout << '\n'; + + // 这里在迭代器中定义的 [] 索引符号 + auto it = container.begin(); + std::cout << it[2] << '\n'; + // std::cout << container[2] << '\n'; 非法 + return 0; +}