码迷,mamicode.com
首页 > 编程语言 > 详细

C++primer 13.5节练习

时间:2017-09-05 14:43:28      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:cat   this   print   pre   ==   namespace   system   har   ons   

练习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 }

 

C++primer 13.5节练习

标签:cat   this   print   pre   ==   namespace   system   har   ons   

原文地址:http://www.cnblogs.com/wuyinfenghappy/p/7478398.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!