您的位置:首页 > 编程语言 > C语言/C++

C++侵入式链表

2015-10-25 16:18 405 查看
C++标准模板库中的list是非侵入式的链表,当我们通过对象来删除容器中的对象时,需要从头到尾查找一次得到iterator,最后通过iterator来删除对象。这样删除容器中的对象时比较缓慢,所以就实现了一个侵入式链表。

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: