标准库中allocator类把内存分配和对象构造分开,首先调用allocator类中的allocate(n), 分配n个T对象的raw空间,随后通过construct函数构造对象。反之,可以通过destroy函数释放对象,最后通过deallocate释放内存。
下面是allocator类分配内存以及构建对象时候,常用的几个方法:
allocator<T> a; |
Defines an allocator object named a that can allocate memory or construct objects of type T. |
a.allocate(n) |
Allocates raw, unconstructed memory to hold n objects of type T. |
a.deallocate(p, n) |
Deallocates memory that held n objects of type T starting at address contained in the T* pointer named p. It is the user's responsibility to run destroy on any objects that were constructed in this memory before calling deallocate. |
a.construct(p, t) |
Constructs a new element in the memory pointed to by the T* pointer p. The copy constructor of type T is run to initialize the object from t. |
a.destroy(p) |
Runs the destructor on the object pointed to by the T* pointer p. |
uninitialized_copy(b, e, b2) |
Copies elements from the input range denoted by iterators b and e into unconstructed, raw memory beginning at iterator b2. The function constructs elements in the destination, rather than assigning them. The destination denoted by b2 is assumed large enough to hold a copy of the elements in the input range. |
uninitialized_fill(b, e, t) |
Initializes objects in the range denoted by iterators b and e as a copy of t. The range is assumed to be unconstructed, raw memory. The objects are constructed using the copy constructor. |
uninitialized_fill_n(b, e, t, n) |
Initializes at most an integral number n objects in the range denoted by iterators b and e as a copy of t. The range is assumed to be at least n elements in size. The objects are constructed using the copy constructor. |
下面是使用allocator类编写的简单的myVector,是标准库中vector的简化版本:
Code
1 #include "stdafx.h"
2 #include <iostream>
3 using std::cout; using std::endl;
4 #include <memory>
5
6 template <class T> class myVector
7 {
8 public:
9 typedef T* iterator;//定义T*别名作为迭代器
10 myVector(): elements(0), first_free(0), end(0) { };
11 ~myVector();
12 void push_back(const T&);
13 size_t size() const { return first_free - elements; }//得到myVector中元素个数
14 size_t capacity() const { return end - elements; } //得到myVector的容量
15 // . . .
16 T& operator[](size_t n) { return elements[n]; }
17 const T& operator[](const size_t n) const { return elements[n]; }
18 void reserve(const size_t n);
19 void resize(const size_t n);
20 void resize(const size_t n, const T& t);//两个resize版本
21 iterator Begin() { return elements;}
22 iterator End() {return first_free;}
23 private:
24 static std::allocator<T> alloc; // 内存分配器
25 void reallocate(); // 重新分配内存,以容纳更多的元素,内存分配策略在这个函数中实施
26 T* elements; // 指向行列式中的第一个元素
27 T* first_free; // 指向行列式中第一个空的元素(未赋值)
28 T* end; // 指向行列式的尾部
29 // . . .
30 };
31
32 #include <algorithm>
33 using std::allocator;
34 template <class T> allocator<T> myVector<T>::alloc;//声明静态变量alloc
35
36 template <class T> myVector<T>::~myVector()
37 {
38 //析构函数释放内存
39
40 // 从后向前的顺序调用destroy,释放T类型对象,注意:destroy会调用T的析构函数
41 for (T *p = first_free; p != elements; /*empty*/ )
42 alloc.destroy(--p);
43
44
45 // elments不为空,释放内存,注意:传递给deallocate是不合法的
46 if (elements)
47 alloc.deallocate(elements, end - elements);
48 }
49
50 using std::max;
51 using std::uninitialized_copy;
52 template <class T> void myVector<T>::reallocate()
53 {
54 //每次分配2倍元素大小的空间
55 std::ptrdiff_t size = first_free - elements;
56 std::ptrdiff_t newcapacity = 2 * max(size, 1);
57 // 分配newcapacity大小的raw内存,以便构造T类型的对象
58 T* newelements = alloc.allocate(newcapacity);
59
60 // 把已经存在的元素拷贝到新的内存中,该函数在newelments构造元素
61 uninitialized_copy(elements, first_free, newelements);
62
63 // 从后向前的顺序调用destroy,释放T类型对象,注意:destroy会调用T的析构函数
64 for (T *p = first_free; p != elements; /*empty*/ )
65 alloc.destroy(--p);
66
67
68 // elments不为空,释放内存
69 if (elements)
70 alloc.deallocate(elements, end - elements);
71
72 // 调整三个指针变量位置
73 elements = newelements;
74 first_free = elements + size;
75 end = elements + newcapacity;
76 }
77
78 template <class T> void myVector<T>::reserve(const size_t n)
79 {
80 if(n>capacity())//小于容量直接忽略掉
81 {
82 std::ptrdiff_t size = first_free - elements;
83 T* newelements = alloc.allocate(n);
84 uninitialized_copy(elements, first_free, newelements);
85 for (T *p = first_free; p != elements; /*empty*/ )
86 alloc.destroy(--p);
87 // elments不为空,释放内存
88 if (elements)
89 alloc.deallocate(elements, end - elements);
90 elements = newelements;
91 first_free = elements + size;
92 end = elements + n;
93
94 }
95 }
96
97 template <class T> void myVector<T>::resize(const size_t n)
98 {
99 size_t size = first_free - elements;
100 size_t capacity = end -elements;
101
102 if( n > capacity)
103 {
104 reallocate();//分配更多空间并拷贝元素
105 unintialized_fill(first_free, elements + n, T());//调用T的默认构造函数
106 }
107 else (n > size)
108 {
109 unintialized_fill(first_free, elements + n, T());
110 }
111 else
112 {
113 for(T *p = first_free; p != elements + n;)
114 {
115 alloc.destroy(--p);
116 }
117 first_free = elements + n;
118 }
119 }
120
121 template <class T> void myVector<T>::resize(const size_t n, const T& t)
122 {
123 size_t size = first_free - elements;
124 size_t capacity = end -elements;
125
126 if( n > capacity)
127 {
128 reallocate();
129 unintialized_fill(first_free, elements + n, t);
130 }
131 else (n > size)
132 {
133 unintialized_fill(first_free, elements + n, t);
134 }
135 else
136 {
137 for(T *p = first_free; p != elements + n;)
138 {
139 alloc.destroy(--p);
140 }
141 first_free = elements + n;
142 }
143 }
144
145 //在myVector中插入一个元素
146 template <class T> void myVector<T>::push_back(const T& t)
147 {
148 // 没有空间了,end指向可使用内存的下一个位置
149 if (first_free == end)
150 reallocate();
151 // 在first_free位置构造t对象
152 alloc.construct(first_free, t);
153 //指针递增
154 ++first_free;
155 }
156
157 int main()
158 {
159 myVector<int> vi;
160 vi.reserve(100);//可以避免多次分配内存
161
162 for (int i = 0; i != 10; ++i)
163 {
164 vi.push_back(i);
165 cout << vi[i] << endl;
166 }
167
168 for (int i = 0; i != 10; ++i)
169 cout << vi[i] << endl;
170
171 //迭代器的使用
172 for(myVector<int>::iterator it = vi.Begin(); it != vi.End(); ++it)
173 cout << *it <<endl;
174 return 0;
175 }