C++侵入式链表
2015-10-25 16:18
405 查看
C++标准模板库中的list是非侵入式的链表,当我们通过对象来删除容器中的对象时,需要从头到尾查找一次得到iterator,最后通过iterator来删除对象。这样删除容器中的对象时比较缓慢,所以就实现了一个侵入式链表。
intrusive_list.h
test.cpp
intrusive_list.h
#ifndef _Intrusive_List_H_ #define _Intrusive_List_H_ // 侵入式链表 template<class T> class intrusive_list { public: struct Node; // 迭代器 class iterator { public: iterator(Node* node) : m_node(node) {} iterator& operator ++() { if (m_node) m_node = m_node->m_next; return *this; } iterator& operator --() { if (m_node) m_node = m_node->m_prev; return *this; } bool operator == (const iterator& iter) { return m_node == iter.m_node; } bool operator != (const iterator& iter) { return !operator ==(iter); } T& operator *() { return *m_node; } T* operator ->() { return m_node; } private: Node* m_node; }; intrusive_list() : m_head(nullptr), m_tail(nullptr) {} ~intrusive_list() { Node* node = m_head; while (node) { Node* next = node->m_next; delete node; node = next; } } // 添加对象 template<class... Args> T* add(Args... args) { Node* node = new Node(args...); if (m_head && m_tail) { node->m_prev = m_tail; m_tail->m_next = node; m_tail = node; } else { m_head = node; m_tail = node; } return node; } // 移除对象 void remove(T* ptr) { Node* node = (Node*)ptr; assert(node->m_valid); if (m_head == node) { m_head = m_head->m_next; } if (m_tail == node) { m_tail = m_tail->m_prev; } if (node->m_prev) node->m_prev->m_next = node->m_next; if (node->m_next) node->m_next->m_prev = node->m_prev; delete node; } iterator begin() { return iterator(m_head); } iterator end() { return iterator(nullptr); } private: struct Node : public T { template<class... Args> Node(Args... args) : T(args...), m_valid(true), m_prev(nullptr), m_next(nullptr) {} bool m_valid; Node* m_prev; Node* m_next; }; Node* m_head; Node* m_tail; }; #endif
test.cpp
int _tmain(int argc, _TCHAR* argv[]) { struct Person { Person(const char* name) : m_name(name) {} std::string m_name; int m_age; }; intrusive_list<Person> lst; Person* p0 = lst.add("11"); lst.add("2"); lst.add("3"); lst.add("4"); lst.add("5"); Person* p1 = lst.add("6"); lst.remove(p0); lst.remove(p1); for (auto iter = lst.begin(); iter != lst.end(); ++iter) { std::cout << iter->m_name << std::endl; } return 0; }
相关文章推荐
- C语言中大小写字母的转化
- c++ 连接数据库
- QT-利用C++仿制windown自带的记事本程序V1.0
- C++多态和虚表(详细)
- C++的一道变态题
- 黑马程序员——OC语言日志——NSArray的介绍和使用
- java中import 与c/c++中的include
- Effective C++:条款38:通过一个复杂的模具has-a要么“基于一些实现”
- 黑马程序员——OC语言日志——NSString字符串的截取、替换,数据类型转换等一些用法
- C++初始化和引用
- 用两个栈实现队列 c++ 9度题目号1512
- C/C++专项练习 (四)
- [C++] Lvalue and Rvalue Reference
- 通过重载new与delete运算符避免向系统重复申请内存从而提高程序运行效率的办法
- 预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)
- 有趣的C语言小程序
- * &
- 关于c语言指针的学习总结1
- 找到数组中重复的和丢失的元素
- C语言<四> 函数与程序结构