1. 程式人生 > >list源碼2(參考STL源碼--侯捷):constructor、push_back、insert

list源碼2(參考STL源碼--侯捷):constructor、push_back、insert

配置 dealloc const return 分享 create 調整 全局函數 iterator

list的push_back、insert的使用如下:

技術分享圖片
#include<bits/stdc++.h>
using namespace std;

int main() {
    int i;
    list<int> l;

    cout<<l.size()<<endl; //0

    l.push_back(1);
    l.push_back(3);
    l.push_back(5);
    l.push_back(7);
    l.push_back(9);
    cout<<l.size()<<endl; //
5 list<int>::iterator it; for(it=l.begin();it!=l.end();++it){ cout<<*it<< ; //1 3 5 7 9 } cout<<endl; it=find(l.begin(),l.end(),5); if(*it==5) l.insert(it,99); for(auto i:l) cout<<i<< ; //1 3 99 5 7 9 cout<<endl; it
=find(l.begin(),l.end(),55); if(*it==55) l.insert(it,20); for(auto i:l) cout<<i<< ; //1 3 99 5 7 9 cout<<endl; it=find(l.begin(),l.end(),55); l.insert(it,20); for(auto i:l) cout<<i<< ; //1 3 99 5 7 9 20 cout<<endl; return 0; }
View Code

list缺省使用alloc作為空間適配器,並據此另外定義了一個list_node_allocator,為的是更方便地以節點大小為配置單位:

template <class T,class Alloc=alloc>
class list{
protected:
    typedef __list_node<T> list_node;
    //專屬之空間適配器,每次配置一個節點大小
    typedef simple_alloc<list_node,Alloc> list_node_allocator;
    ...
};

於是list_node_allocator(n)表示配置n個節點空間,以下4個函數,分別來配置、釋放、構造、銷毀一個節點:

protected:
    //配置一個節點並傳回
    link_type get_node(){return list_node_allocator::allocate();}
    //釋放一個節點
    void put_node(link_type p){list_node_allocator::deallocate(p);}
    //產生(配置並構造)一個節點,帶有元素值
    link_type create_node(const T& x){
        linke_type p=get_node();
        construct(&p->data,x);//全局函數,構造/析構基本工具
        return p;
    }
    //銷毀(析構並釋放)一個節點
    void destory_node(link_type p){
        destory(&p->data);
        put_node(p);//全局函數,構造/析構基本工具
    }

list提供有許多constructors,其中一個是default constructor,允許我們不指定任何參數做出一個空的list出來:

public:
    list(){empty_initialize();} //產生一個空鏈表
protected:
    void empty_initialize(){
        node=get_node(); //配置一個節點空間,令node指向它
        node->next=node; //令node的頭尾指向自己,不設元素值
        node->prev=node;
    }

技術分享圖片

當我們以push_back()將新元素插入list尾端時,此函數內部調用insert():

void push_back(const T& x) {insert(end(),x);}

insert()是一個重載函數,有多種形式,其中最簡單的一種如下,符合以上所需,首先配置並構造一個節點,然後在尾端進行適當的指針操作,將新節點插入進去:

//函數的目的:在叠代器position所指位置插入一個節點,內容為x
    iterator insert(iterator position,const T& x){
        link_type temp=create_node(x);//產生一個節點
        //調整雙向指針,使temp插入進去
        temp->next=position.node;
        temp->prev=position.node->prev;
        (link_type(position.node->prev))->next=temp;
        position.node->prev=temp;
        return temp;
    }

由於list不像vector那樣有可能在空間不足時做重新配置,數據移動的操作,所以插入之前的叠代器仍然有效。

list源碼2(參考STL源碼--侯捷):constructor、push_back、insert