vector容器部分原始碼實現

2021-07-11 23:25:49 字數 4281 閱讀 1299

stl中vector部分原始碼實現

本次作業要求自己模仿實現stl中vector部分函式

為了檢測記憶體的管理機制是否是像原始碼一樣,額外寫了乙個test類,通過輸出來檢測是否一樣。

test**如下:

#ifndef __test_h__

#define __test_h__

#include

#include

class testallocator : public

std::allocator

//這個函式用來釋放記憶體,並不涉及呼叫在這片記憶體上面變數的析構函式,其中p是這片記憶體的首位址,size是這片位址的大小

void deallocate(int * p, std::size_t size)

//在已經申請了的記憶體上面建立乙個新的變數,其中p是乙個指標,指向我們要建立新的變數的位址,val是變數的值

void construct(int * p, int val)

//在指標p指向的記憶體上,銷毀掉變數,但是並不釋放記憶體

void destroy(int * p)

};#endif

為了防止一些人投機取巧使用#define myvector std::vector

所以額外寫出了乙個類base來防止這種情況

#ifndef __base_h__

#define __base_h__

#define vector not_allowed

#define define not_allowed

class

base {};

#endif

在類myvector中要繼承自定義的base,這樣就可以防止#define myvector std::vector的情況

因為stl的vector是不可能繼承自自定義的base的,在測試函式中有一句是檢查是否繼承自base

接下來放上具體**,並解釋其中一些寫的過程中覺得比較難懂的知識點

//

// vector.h:

// c++

//// created by 舒俊淮 on 16/5/22.

//#ifndef __vector_h__

#define __vector_h__

#define a alloc()

#include "base.h"

#include "memory"

#include "test.h"

using

namespace

std;

/*typename alloc = std::allocator這是乙個模板變數,型別名叫alloc,接受分配器,如這裡的testallocator

「= std::allocator」的意思是,預設呼叫t型別的allocator,比如寫的是myvector,沒有提供第二個引數,就使用預設值*/

template

< typename t, typename alloc = std::allocator>

class myvector : public base

myvector(const size_t &n, const t &ele, alloc _a = alloc())

template

myvector(inputiterator begin, inputiterator end, alloc _a = alloc())

myvector(const myvector &other)

~myvector()

}myvector & operator=(const myvector &other)

_size = other._size;

_capacity = other._capacity;

_data = a.allocate(_capacity);

for (int i = 0; i < _size; ++i)

a.construct(_data + i, *(other._data + i));

}return *this;

}iterator begin()

const_iterator begin() const

iterator end()

const_iterator end() const

// capacity

size_t size() const

void resize(const size_t &num)

for (int i = _size; i < num; ++i)

a.construct(_data + i, t());

_size = num;

} else

}void resize(const size_t &num, const t &n)

for (int i = _size; i < num; ++i)

a.construct(_data + i, n);

_size = num;

} else

}size_t capacity() const

bool empty() const

void reserve(const size_t &newcap)

a.deallocate(_data, _capacity);

_capacity = newcap;

_data = tmp;}}

// element access

t & operator(const size_t &index)

const t & operator(const size_t &index) const

t & front()

const t & front() const

t & back()

const t & back() const

t * data()

const t * data() const

// modifiers

template

void assign(inputiterator begin, inputiterator end) else

}void assign(const size_t &size, const t &n) else

}void push_back(const t &n) else

}void pop_back()

}void clear()

}private:

iterator _data;

size_t _size, _capacity;

};#endif

下面是測試函式:

#include 

#include "test.h"

#include "base.h"

#include "vector.h"

int main()

最後,說明一下在寫的過程中個人比較迷惑最後弄懂了的知識點:

首先,一般來說出了作用域所有變數都會被析構。

而臨時物件被析構的時間比較早,是在建立它的語句執行完之後,立刻被析構!

比如上面函式中的alloc().allocate(),alloc()是乙個類的預設建構函式,它建立乙個物件並且使用了類的成員函式allocate()。

執行完這個語句之後,這個剛剛被建立的物件就會被銷毀。所以上面的**不會出現類alloc的物件堆積如山的情況。

為什麼上面的**要這麼寫呢?因為我們需要用到testallocator這個類中的函式,又不想宣告太多的testallocator物件(很浪費),所以採用了臨時變數的方法。

至於如何判斷臨時物件,乙個簡單的方法是看看它被構造之後有沒有引用指向它,即,構造的時候有沒有左值!

比如下面兩行:

temp = alloc();這裡建立的不是乙個臨時變數,所以temp的析構是發生在退出作用域時。

alloc();這個建立了乙個臨時變數,在執行完該語句之後立刻被析構。(呼叫析構函式~alloc())

還有一種情況是for語句,如:

for (int i = 0; i < 5; ++i) {}

在for語句執行完之後,臨時變數i即被銷毀。

下面是兩個相關的例子,感受一下其中細微的差別:

STL原始碼剖析 容器 vector

vector 常被稱為向量容器,因為該容器擅長在尾部插入或刪除元素,在常量時間內就可以完成,時間複雜度為o 1 而對於在容器頭部或者中部插入或刪除元素,則花費時間要長一些 移動元素需要耗費時間 時間複雜度為線性階o n vector實現的關鍵在於其對大小的控制以及重新配置時的資料移動效率。vecto...

容器vector部分功能的實現

這是c primer書中的例題。實現了vector容器的部分功能。具體內容在第四版的18.1節。要考慮到vector的記憶體分配策略。下面分別是用allocator 注釋的部分 和new,delete實現的。1.allocator allocate size t t 分配原始的未構造記憶體以儲存t個...

JDK原始碼閱讀 Vector實現

vector同樣繼承自abstractlist,與arraylist linedlist一樣,是list的一種實現 與arraylist一樣,也是使用物件陣列儲存元素 protected object elementdata 記錄元素的個數 protected intelementcount 每次動...