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 每次動...