练习13.39
1 #include <iostream> 2 #include <string> 3 #include <utility> 4 #include <memory> 5 6 using namespace std; 7 8 class StrVec { 9 public: 10 StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) {} 11 StrVec(const StrVec&); 12 StrVec& operator=(const StrVec&); 13 ~StrVec(); 14 void push_back(const string &); 15 size_t size() const { return first_free - elements; } 16 size_t capacity() const { return cap - elements; } 17 string *begin() const { return elements; } 18 string *end() const { return first_free; } 19 private: 20 string *elements; 21 string *first_free; 22 string *cap; 23 pair<string *, string *> alloc_n_copy(const string *, const string *); 24 void chk_n_alloc() { if (size() == capacity()) reallocate(); } 25 static allocator<string> alloc; 26 void free(); 27 void reallocate(); 28 }; 29 30 int main() 31 { 32 system("pause"); 33 return 0; 34 } 35 36 StrVec::StrVec(const StrVec &s) 37 { 38 auto newdata = alloc_n_copy(s.begin(), s.end()); 39 elements = newdata.first; 40 first_free = cap = newdata.second; 41 } 42 43 StrVec & StrVec::operator=(const StrVec &rhs) 44 { 45 auto data = alloc_n_copy(rhs.begin(), rhs.end()); 46 free(); 47 elements = data.first; 48 first_free = cap = data.second; 49 return *this; 50 } 51 52 StrVec::~StrVec() 53 { 54 free(); 55 } 56 57 void StrVec::push_back(const string &s) 58 { 59 chk_n_alloc(); 60 alloc.construct(first_free++, s); 61 } 62 63 pair<string*, string*> StrVec::alloc_n_copy(const string *b, const string *e) 64 { 65 auto data = alloc.allocate(e - b); 66 return{ data,uninitialized_copy(b,e,data) }; 67 } 68 69 void StrVec::free() 70 { 71 if (elements) 72 { 73 for (auto p = first_free; p != elements;) 74 alloc.destroy(--p); 75 alloc.deallocate(elements, cap - elements); 76 } 77 } 78 79 void StrVec::reallocate() 80 { 81 auto newcapacity = size() ? 2 * size() : 1; 82 auto newdata = alloc.allocate(newcapacity); 83 auto dest = newdata; 84 auto elem = elements; 85 for (size_t i = 0; i != size(); ++i) 86 alloc.construct(++dest, std::move(*elem++)); 87 free(); 88 elements = newdata; 89 first_free = dest; 90 cap = elements + newcapacity; 91 }
练习13.40
1 #include <iostream> 2 #include <string> 3 #include <utility> 4 #include <memory> 5 6 using namespace std; 7 8 class StrVec { 9 public: 10 StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) {} 11 StrVec(const initializer_list<string> &s); 12 StrVec(const StrVec&); 13 StrVec& operator=(const StrVec&); 14 ~StrVec(); 15 void push_back(const string &); 16 size_t size() const { return first_free - elements; } 17 size_t capacity() const { return cap - elements; } 18 string *begin() const { return elements; } 19 string *end() const { return first_free; } 20 void resize(size_t n, const string&); 21 void Reserve(const size_t& len);//重新分配大小 22 private: 23 string *elements; 24 string *first_free; 25 string *cap; 26 pair<string *, string *> alloc_n_copy(const string *, const string *); 27 void chk_n_alloc() { if (size() == capacity()) reallocate(); } 28 static allocator<string> alloc; 29 void free(); 30 void reallocate(); 31 }; 32 33 int main() 34 { 35 system("pause"); 36 return 0; 37 } 38 39 StrVec::StrVec(const initializer_list<string>& s) 40 { 41 auto newzone = alloc_n_copy(s.begin(), s.end()); 42 elements = newzone.first; 43 first_free = cap = newzone.second; 44 } 45 46 /*StrVec(const initializer_list<string> &vs) 47 { 48 elements = nullptr; 49 first_free = nullptr; 50 cap = nullptr; 51 for (auto it : vs) 52 this->Push_back(it); 53 }*/ //这两种都行应该 54 55 StrVec::StrVec(const StrVec &s) 56 { 57 auto newdata = alloc_n_copy(s.begin(), s.end()); 58 elements = newdata.first; 59 first_free = cap = newdata.second; 60 } 61 62 StrVec & StrVec::operator=(const StrVec &rhs) 63 { 64 auto data = alloc_n_copy(rhs.begin(), rhs.end()); 65 free(); 66 elements = data.first; 67 first_free = cap = data.second; 68 return *this; 69 } 70 71 StrVec::~StrVec() 72 { 73 free(); 74 } 75 76 void StrVec::push_back(const string &s) 77 { 78 chk_n_alloc(); 79 alloc.construct(first_free++, s); 80 } 81 82 void StrVec::resize(size_t n, const string &s) 83 { 84 if (n == size()) 85 return; 86 else if (n > size()) 87 { 88 if (n > capacity()) 89 { 90 Reserve(n); 91 for (auto i = 0; i != n - size();) 92 alloc.construct(first_free++, s); 93 } 94 else 95 { 96 for (auto i = 0; i != n - size();) 97 alloc.construct(first_free++, s); 98 } 99 } 100 else 101 { 102 auto flag = first_free; 103 while (first_free - elements != n) 104 alloc.destroy(--first_free); 105 alloc.deallocate(flag, size() - n); 106 } 107 } 108 109 pair<string*, string*> StrVec::alloc_n_copy(const string *b, const string *e) 110 { 111 auto data = alloc.allocate(e - b); 112 return{ data,uninitialized_copy(b,e,data) }; 113 } 114 115 void StrVec::free() 116 { 117 if (elements) 118 { 119 for (auto p = first_free; p != elements;) 120 alloc.destroy(--p); 121 alloc.deallocate(elements, cap - elements); 122 } 123 } 124 125 void StrVec::reallocate() 126 { 127 auto newcapacity = size() ? 2 * size() : 1; 128 auto newdata = alloc.allocate(newcapacity); 129 auto dest = newdata; 130 auto elem = elements; 131 for (size_t i = 0; i != size(); ++i) 132 alloc.construct(++dest, std::move(*elem++)); 133 free(); 134 elements = newdata; 135 first_free = dest; 136 cap = elements + newcapacity; 137 } 138 139 void StrVec::Reserve(const size_t& len)//重新分配大小 140 { 141 if (len <= cap - elements)//小于或等于不申请 142 return; 143 //未构造的内存减少 144 auto newcapacity = len; 145 auto newdata = alloc.allocate(newcapacity);//申请len倍内存 146 auto dest = newdata;//alloc返回的首指针 147 auto elem = elements; 148 for (size_t i = 0;i != size();++i) 149 alloc.construct(dest++, move(*elem++)); 150 free(); 151 elements = newdata;//新的首指针 152 first_free = dest; 153 cap = elements + newcapacity; 154 }
练习13.41
因为first_free所指的位置是最后一个存放元素后一个位置,所以应该用后置递增运算,这样就能依次的进行添加,如果用前置,中间会空出一个内存,这种情况是未定义的;
练习13.42
将原先的代码的vector模板改为StrVec类就可以了
练习13.43
1 void StrVec::free() 2 { 3 if (elements) 4 { 5 for_each(elements, first_free, [this](string &p) { alloc.destroy(&p);}); 6 /*for (auto p = first_free; p != elements;) 7 alloc.destroy(--p);*/ 8 alloc.deallocate(elements, cap - elements); 9 } 10 }
练习13.44
1 #include <iostream> 2 #include <string> 3 #include <utility> 4 #include <memory> 5 #include <algorithm> 6 7 using namespace std; 8 9 class String { 10 friend ostream &print(ostream &os, String &s); 11 public: 12 String(): element(nullptr), first_free(nullptr) {} 13 String(char *); 14 private: 15 static allocator<char> alloc; 16 char *element; 17 char *first_free; 18 }; 19 allocator<char> String::alloc; 20 ostream &print(ostream &os, String &s); 21 22 int main() 23 { 24 String s1; 25 String s2("hello"); 26 String s3("hello world"); 27 print(cout, s1); 28 print(cout, s2); 29 print(cout, s3); 30 system("pause"); 31 return 0; 32 } 33 34 String::String(char *s) 35 { 36 int i = 0; 37 while (s[i] != ‘\0‘) 38 ++i; 39 auto newloc = alloc.allocate(i); 40 auto dest = newloc; 41 for (auto count = 0; count != i;++count) 42 alloc.construct(dest++, s[count]); 43 element = newloc; 44 first_free = dest; 45 } 46 47 ostream & print(ostream &os,String &s) 48 { 49 while (s.element != s.first_free) 50 { 51 os << *(s.element); 52 s.element++; 53 } 54 cout << endl; 55 return os; 56 // TODO: 在此处插入 return 语句 57 }
时间: 2024-11-09 00:56:59