C++侵入式链表

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;
}
原文地址:https://www.cnblogs.com/dongc/p/4908933.html