vector實現(只能裝入string)

  1 #include<iostream>
  2 #include<string>
  3 #include<memory>
  4 #include<utility>
  5 using namespace std;
  6 
  7 class StrVec {
  8 public:
  9     StrVec():element(nullptr),first_free(nullptr),cap(nullptr){}   // 默認構造函數
 10     StrVec(const StrVec&); //拷貝構造函數
 11     StrVec &operator=(const StrVec&); //賦值拷貝運算符
 12     ~StrVec();
 13 
 14     void push_back(const string&);
 15 
 16     size_t size() const {
 17         return first_free - element;
 18     }
 19     size_t capacity()const {
 20         return cap - element;
 21     }
 22     string *begin() const {
 23         return element;
 24     }
 25     string *end()const {
 26         return first_free;
 27     }
 28 
 29 private:
 30     static allocator<string> alloc;
 31 
 32     void chk_n_alloc() {
 33         if (size() == capacity())
 34             reallocate();
 35     }
 36     pair<string*, string*> alloc_n_copy(const string*, const string*);  // 用於被copy控制成員調用
 37 
 38     void free();
 39     void reallocate();  //得到另外一塊更大的內存(釋放原有內存)並拷貝已有元素   (實現的是標準庫vector的內存分配機制)
 40     string *element; // 數組首地址
 41     string *first_free;
 42     string *cap;
 43 
 44 };
 45 
 46 
 47 void StrVec::push_back(const string& s)
 48 {
 49     chk_n_alloc();
 50     alloc.construct(first_free++, s);
 51 }
 52 
 53 pair<string*, string*> StrVec::alloc_n_copy(const string *b, const string *e)
 54 {
 55     auto data = alloc.allocate(e - b);
 56     return { data,uninitialized_copy(b,e,data) };
 57 }
 58 
 59 
 60 void StrVec::free()
 61 {
 62     if (element) {
 63         for (auto p = first_free; p != element;)
 64             alloc.destroy(--p);
 65         alloc.deallocate(element, cap - element);
 66     }
 67 }
 68 
 69 
 70 StrVec::StrVec(const StrVec& s)
 71 {
 72     //調用alloc_n_copy分配空間以容納與s中同樣多的元素
 73     auto newdate = alloc_n_copy(s.begin(), s.end());
 74     element = newdate.first;
 75     first_free = newdate.second;
 76 }
 77 
 78 StrVec::~StrVec()
 79 {
 80     free();
 81 }
 82 
 83 StrVec& StrVec::operator=(const StrVec& rhs)
 84 {
 85     auto data = alloc_n_copy(rhs.begin(), rhs.end());
 86     free();
 87     element = data.first;
 88     first_free = cap = data.second;
 89     return *this;
 90 }
 91 
 92 //在一個新的,更大的string數組分配內存
 93 //在內存空間的前一部分構造對象,保存現有元素
 94 //銷燬原內存中的元素,並釋放這塊內存
 95 void StrVec::reallocate()   
 96 {
 97     //分配當前大小兩倍的內存空間
 98     auto newCapacity = size() ? 2 * size() : 1;
 99     auto newdata = alloc.allocate(newCapacity);
100 
101     auto dest = newdata;  // 新內存首地址
102     auto elem = element;  // 舊內存首地址
103 
104     for (size_t i = 0; i != size(); ++i)
105         alloc.construct(dest++, std::move(*elem++));        // 由於vector從新分配內存,會將原來的數據銷燬,不必拷貝,這裏使用移動拷貝來提升效率
106     free();
107     element = newdata;
108     first_free = dest;
109     cap = element + newCapacity;
110 
111 }
相關文章
相關標籤/搜索