山寨STL實現之list

2022-04-28 06:23:36 字數 3077 閱讀 1583

在stl中list是以雙向鍊錶的方式來儲存的,應此使用給定的下標值來找到對應的節點所需的時間複雜度為o(n),相比vector直接使用原生指標會慢一些。

因為是雙向鍊錶的關係,那麼必然有一種結構來表示鍊錶中的節點。

template 

struct __list_node

__list_node(const t& x) : prev(null), next(null), data(x)

};然後我們定義出其iterator和const_iterator的結構

template 

struct __list_iterator

__list_iterator(const __list_const_iterator& x) : node(x.node)

__list_iterator() : node(null)

inline iterator& operator++()

inline iterator operator++(int)

inline iterator& operator--()

inline iterator operator--(int)

inline reference operator*()const

inline bool

operator==(const iterator& x)const

inline bool

operator!=(const iterator& x)const

};由於const_iterator與iterator的結構類似,這裡不再貼出。其中過載了++與--運算子,實際上就是節點的前後移動。

然後看一下list的定義

template 

class list

讓我們來看看list中的別名

public:

typedef t                        value_type;

typedef t*                       pointer;

typedef __list_iteratoriterator;

typedef __list_const_iteratorconst_iterator;

typedef t&                       reference;

typedef const t&                 const_reference;

typedef size_t                   size_type;

typedef ptrdiff_t                difference_type;

typedef reverse_iteratorconst_reverse_iterator;

typedef reverse_iteratorreverse_iterator;

下面是其內部的成員變數

protected:

typedef __list_node*           link_type;

typedef listself;

typedef allocator<__list_node> node_alloc;

link_type node;

size_type length;

在stl中從begin到end總是以乙個前閉後開的形式來表示的,應此我們給出乙個node節點來表示end所指位置,而node節點的前驅則是這個list的起始節點,而length則儲存了這個list的元素數量。

下面來看看list中最基本的建構函式和析構函式

list() : length(0)

~list()

在list物件構造之初,首先構造出node節點,使其的前驅和後繼都指向其本身,應此通過begin和end拿出的迭代器為同乙個。在list物件析構時,首先將這個list清空,然後將構造出的node節點釋放掉。

然後是其begin和end方法,用來獲取第乙個元素和最後乙個元素的後乙個元素的迭代器

inline iterator begin()

inline const_iterator begin()const

inline iterator end()

inline const_iterator end()const

front和back分別被用來獲取第乙個元素和最後乙個元素

inline reference front()

inline const_reference front()const

inline reference back()

inline const_reference back()const

empty、size分別被用來判別容器是否為空、獲取容器內元素的個數

inline bool empty()const

inline size_type size()const

list與vector不同的是list是雙向的,應此它允許從頭尾兩個方向來插入和刪除元素

inline void push_front(const t& x)

inline void push_back(const t& x)

inline void pop_front()

inline void pop_back()

然後我們來看一下push的本質,insert函式

iterator insert(const iterator& position, const t& x)

這裡首先會檢查這個迭代器是否屬於這個list,然後構造出乙個新節點,並把它插入到這個迭代器的前面,最後將節點數+1。

然後是其刪除節點函式erase

void erase(const iterator& position)

這裡同樣會檢查這個迭代器是否屬於這個list,然後將這個節點移除,最後析構並釋放記憶體空間。

最後讓我們來看一下list中過載的運算子

self& operator=(const self& x)

reference operator(size_type n)

else

return current->data;

}inline value_type at(size_type n)

山寨STL實現之vector

首先是vector的定義 template class vector 讓我們先來看看vector中的一些別名 public typedef t value type typedef t pointer typedef t reference typedef const t const referen...

山寨STL實現之allocator

作為乙個山寨的stl,那麼不得不提的是其中的allocator 空間配置器 顧名思義,它是負責空間分配用的,下面 十分簡單,僅對c函式malloc和free進行了薄薄的一層封裝,同時給定了自定義函式free handler用於在空間分配時候由於記憶體被佔滿了而導致的分配失敗。這裡值得注意的是 這個釋...

山寨STL實現之記憶體池

記憶體池的作用 減少記憶體碎片,提高效能。首先不得不提的是win32和x64中對於指標的長度是不同的,在win32中乙個指標佔4位元組,而在x64中乙個指標佔8位元組。也正是不清楚這一點,當我在x64中將指標作為4位元組修改造成其他資料異常。首先我們先來定義三個巨集 define align siz...