1 #include <iostream> 2 #include <vector> 3 #include <memory> 4 #include <thread> 5 #include <type_traits> 6 #include <typeinfo> 7 #include <sstream> 8 #include <utility> 9 10 11 class StrVec 12 { 13 friend std::ostream &operator<<(std::ostream &os, const StrVec &rhs); 14 15 private: 16 std::string *elemnets_; 17 std::string *memry_free; 18 std::string *cap; 19 std::allocator<std::string> alloc;//为所有StrVec分配内存 20 21 //申请2倍范围空间,并把范围移动到新空间 22 std::pair<std::string *, std::string *> alloc_n_copy(const std::string *beg, const std::string *end) 23 { 24 auto new_memry = alloc.allocate(end - beg); 25 return {new_memry, std::uninitialized_copy(beg, end, new_memry)}; 26 }; 27 28 29 void free() //释放目前申请的内存 30 { 31 for (auto ptr = memry_free; ptr != elemnets_;) 32 { 33 alloc.destroy(--ptr); 34 } 35 36 alloc.deallocate(elemnets_, memry_free - elemnets_); 37 } 38 39 void realloctor() //重新申请大于目前2倍空间; 40 { 41 auto newcapacity = size() ? 2 * size() : 1; 42 auto newmemery = alloc.allocate(newcapacity); 43 auto dest = newmemery; 44 auto elem = elemnets_;//指向当前对象的头 45 for (size_t i = 0; i != size(); ++i) 46 { 47 //move会让elem指向的string对象放弃自己的内存管理权并返回,然后construct使用string的移动构造函数构建dest指向的地址 48 alloc.construct(dest++, std::move(*elem++)); 49 } 50 free(); 51 elemnets_ = newmemery; 52 memry_free = dest; 53 cap = elemnets_ + newcapacity; 54 }; 55 56 void Chk_n_alloc() 57 { 58 if (size() == capacity()) 59 realloctor(); 60 } 61 62 public: 63 StrVec() : elemnets_(nullptr), memry_free(nullptr), cap(nullptr) 64 {} 65 66 StrVec(std::initializer_list<std::string> li) 67 { 68 auto newadress = alloc_n_copy(li.begin(), li.end()); 69 elemnets_ = newadress.first; 70 cap = memry_free = newadress.second; 71 } 72 73 //只是构造(每次想着释放- -) 74 StrVec(const StrVec &rhs) 75 { 76 auto newadress = alloc_n_copy(rhs.begin(), rhs.end()); 77 elemnets_ = newadress.first; 78 cap = memry_free = newadress.second; 79 } 80 81 StrVec(StrVec &&rhs) 82 : elemnets_(rhs.elemnets_), memry_free(rhs.memry_free), cap(rhs.cap) 83 { 84 //置空 85 rhs.elemnets_ = rhs.cap = rhs.memry_free = nullptr; 86 } 87 88 StrVec &operator=(const StrVec &rhs) 89 { 90 if (&rhs != this) 91 { 92 auto newadress = alloc_n_copy(rhs.begin(), rhs.end()); 93 free(); 94 elemnets_ = newadress.first; 95 memry_free = cap = newadress.second; 96 } 97 return *this; 98 } 99 100 StrVec &operator=(StrVec &&rhs) 101 { 102 if (&rhs != this) 103 { 104 elemnets_ = rhs.elemnets_; 105 memry_free = rhs.memry_free; 106 cap = rhs.cap; 107 rhs.elemnets_ = rhs.cap = rhs.memry_free = nullptr; 108 } 109 return *this; 110 } 111 112 //列表赋值初始化 113 StrVec &operator=(std::initializer_list<std::string> li) 114 { 115 auto newadress = alloc_n_copy(li.begin(), li.end()); 116 free(); 117 elemnets_ = newadress.first; 118 memry_free = cap = newadress.second; 119 120 return *this; 121 } 122 123 124 std::string &operator[](std::size_t size_) 125 { 126 return elemnets_[size_]; 127 } 128 129 std::string &operator[](std::size_t size) const 130 { 131 return elemnets_[size]; 132 133 } 134 135 136 bool operator==(const StrVec &s) 137 { 138 if (size() != s.size()) 139 return false; 140 auto it = elemnets_, its = s.elemnets_; 141 while (it != memry_free) 142 { 143 if (*it++ != *its++) 144 return false; 145 } 146 return true; 147 } 148 149 150 bool operator<(const StrVec &rhs) 151 { 152 if (this->size() < rhs.size()) 153 { 154 return true; 155 } else if (this->size() > rhs.size()) 156 { 157 return false; 158 } 159 160 auto rhs_elemte = rhs.elemnets_; 161 for (auto iter_ptr = elemnets_; iter_ptr != memry_free;) 162 { 163 if (*iter_ptr++ > *rhs_elemte++) 164 { 165 return false; 166 } else 167 { 168 return true; 169 } 170 } 171 return false; 172 } 173 174 bool operator>(const StrVec &rhs) 175 { 176 return !(*this < rhs) && (this != &rhs); 177 } 178 179 bool operator!=(const StrVec &rhs) 180 { 181 return !(*this == rhs); 182 } 183 184 185 public: 186 template<typename ...Args> 187 void emplace_back(Args &&... paracage) 188 { 189 Chk_n_alloc(); 190 alloc.construct(memry_free++, std::forward<Args>(paracage)...); 191 } 192 193 void push_back(const std::string &s) 194 { 195 Chk_n_alloc();//确保空间剩余 196 alloc.construct(memry_free++, s);//在尾后构建一个s(s的拷贝构造函数构造),并把尾后指针first_free指向下一个 197 } 198 199 void pop_back() 200 { 201 if (memry_free != elemnets_) 202 { 203 alloc.destroy(--memry_free); 204 } 205 } 206 207 208 std::size_t size() const 209 { 210 return memry_free - elemnets_; 211 } 212 213 std::size_t capacity() const 214 { 215 return cap - elemnets_; 216 } 217 218 std::string *begin() const 219 { 220 return elemnets_; 221 } 222 223 std::string *end() const 224 { 225 return memry_free; 226 } 227 }; 228 229 230 std::ostream &operator<<(std::ostream &os, const StrVec &rhs) 231 { 232 for (auto ptr = rhs.elemnets_; ptr != rhs.memry_free;) 233 { 234 os << *ptr++ << " "; 235 } 236 237 return os; 238 } 239 240 241 int main(int argc, char *argv[]) 242 { 243 244 StrVec strvec{"Hello", "World", "this", "std::string", "vector<std::string>"}; 245 std::cout << strvec; 246 std::cout << strvec[3] << std::endl; 247 strvec.push_back("你好"); 248 std::cout << strvec[5] << std::endl; 249 250 std::cout << "------------" << std::endl; 251 std::cout << strvec; 252 strvec.pop_back(); 253 strvec.pop_back(); 254 strvec.pop_back(); 255 strvec.pop_back(); 256 std::cout << "------------" << std::endl; 257 std::cout<<strvec; 258 std::cout << "------------" << std::endl; 259 strvec.emplace_back("其实emeplace通过参数包转发给std::string的构造"); 260 strvec.emplace_back(10,'c'); 261 std::cout<<strvec; 262 263 return 0; 264 }