Skip to content

Commit b56a7e2

Browse files
committed
2015-4-30 improved StrVec
1 parent 9786cbb commit b56a7e2

File tree

3 files changed

+202
-0
lines changed

3 files changed

+202
-0
lines changed

C++PrimerTest/exercise13.5StrVec

92.4 KB
Binary file not shown.

C++PrimerTest/exercise13.5StrVec.cpp

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
#include "exercise13.5StrVec.h"
2+
3+
void StrVec::push_back(const string& s)
4+
{
5+
chk_n_alloc(); //确保有足够空间容纳新元素
6+
alloc.construct(firstfree++, s); //构造新元素
7+
}
8+
9+
pair<string*, string*> StrVec::alloc_n_copy(const string* s1, const string* s2)
10+
{
11+
auto data = alloc.allocate(s2-s1);
12+
return {data, uninitialized_copy(s1, s2, data)};
13+
}
14+
15+
/**
16+
*free()
17+
*首先销毁元素, 然后释放所有内存
18+
*/
19+
void StrVec::free()
20+
{
21+
if(elements)
22+
{
23+
// for(auto p = firstfree; p!=elements;)
24+
// alloc.destroy(--p);
25+
for_each(elements, firstfree, [this](string& str){alloc.destroy(&str);});
26+
alloc.deallocate(elements, cap-elements);
27+
}
28+
}
29+
StrVec::StrVec(const StrVec& str)
30+
{
31+
auto temp = alloc_n_copy(str.begin(), str.end());
32+
elements = temp.first;
33+
firstfree = cap = temp.second;
34+
}
35+
36+
/**
37+
*StrVec(initializer_list<string> strlist)
38+
*使用初始化列表的构造函数
39+
*/
40+
StrVec::StrVec(initializer_list<string> strlist)
41+
{
42+
auto newcapacity = strlist.size()*2;
43+
auto data = alloc.allocate(newcapacity);
44+
auto fisfree = uninitialized_copy(strlist.begin(), strlist.end(), data);
45+
elements = data;
46+
firstfree = fisfree;
47+
cap = elements + newcapacity;
48+
}
49+
StrVec& StrVec::operator=(const StrVec& rhs)
50+
{
51+
auto data = alloc_n_copy(rhs.begin(), rhs.end());
52+
free();
53+
elements = data.first;
54+
firstfree = cap = data.second;
55+
return *this;
56+
}
57+
StrVec::~StrVec()
58+
{
59+
free();
60+
}
61+
/**
62+
*reallocate()
63+
*
64+
*/
65+
void StrVec::reallocate()
66+
{
67+
auto newcapacity = size() ? size()*2:1;
68+
auto newdata = alloc.allocate(newcapacity);
69+
70+
auto dest = newdata;
71+
auto elem = elements;
72+
for(size_t i=0; i<size(); i++)
73+
{
74+
alloc.construct(dest++, std::move(*elem++));
75+
}
76+
77+
free();
78+
elements = newdata;
79+
firstfree = dest;
80+
cap = elements + newcapacity;
81+
82+
}
83+
84+
void StrVec::reserve(size_t n)
85+
{
86+
size_t old_capacity = capacity();
87+
if(n > old_capacity)
88+
{
89+
auto newcapacity = n;
90+
auto newdata = alloc.allocate(newcapacity);
91+
92+
auto dest = newdata;
93+
auto elem = elements;
94+
for(size_t i=0; i<size(); i++)
95+
{
96+
alloc.construct(dest++, std::move(*elem++));
97+
}
98+
99+
free();
100+
elements = newdata;
101+
firstfree = dest;
102+
cap = elements + newcapacity;
103+
}
104+
}
105+
106+
void StrVec::resize(size_t n)
107+
{
108+
if(n > capacity())
109+
{
110+
111+
throw out_of_range("out of range!");
112+
return;
113+
114+
}
115+
116+
else if(n>size())
117+
{
118+
auto count = n - size();
119+
uninitialized_fill_n(firstfree, count, "");
120+
}
121+
}
122+
123+
void StrVec::resize(size_t n, string str)
124+
{
125+
if(n > capacity())
126+
{
127+
128+
throw out_of_range("out of range!");
129+
return;
130+
}
131+
132+
else if(n>size())
133+
{
134+
auto count = n - size();
135+
uninitialized_fill_n(firstfree, count, str);
136+
}
137+
}
138+
139+
int main()
140+
{
141+
StrVec test{"xianguy", "love", "liuchang"};
142+
test.push_back("xiangyu");
143+
test.push_back("liuchang");
144+
cout << "capacity: " << test.capacity() << endl;
145+
cout << "size: " << test.size() << endl;
146+
for(auto it=test.begin(); it !=test.end(); it++)
147+
{
148+
cout << *it << endl;
149+
}
150+
return 0;
151+
}

C++PrimerTest/exercise13.5StrVec.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <iostream>
2+
#include <string>
3+
#include <memory>
4+
#include <utility>
5+
#include <stdexcept>
6+
#include <initializer_list>
7+
#include <algorithm>
8+
9+
using namespace std;
10+
//allocator<string> alloc;
11+
class StrVec
12+
{
13+
private:
14+
string* elements; //指向分配内存中的首元素
15+
string* firstfree; //指向最后一个实际元素之后的位置
16+
string* cap; //指向分配的内存末尾之后的位置
17+
allocator<string> alloc; //分配元素
18+
void chk_n_alloc()
19+
{
20+
if(size() == capacity())
21+
reallocate();
22+
}
23+
pair<string*, string*> alloc_n_copy(const string*, const string*);
24+
void free();
25+
void reallocate();
26+
public:
27+
StrVec():
28+
elements(nullptr), firstfree(nullptr), cap(nullptr) {}
29+
StrVec(initializer_list<string> strlist);
30+
StrVec(const StrVec&); //拷贝构造函数
31+
StrVec& operator=(const StrVec&); //赋值构造函数
32+
~StrVec();
33+
void push_back(const string&);
34+
size_t size()
35+
{return (firstfree - elements);}
36+
size_t capacity()
37+
{return (cap - elements);}
38+
string* begin() const
39+
{
40+
return elements;
41+
}
42+
string* end() const
43+
{
44+
return firstfree;
45+
}
46+
void reserve(size_t n);
47+
void resize(size_t n);
48+
void resize(size_t n, string str);
49+
50+
51+
};

0 commit comments

Comments
 (0)