我们知道,c++中分配对象和删除对象常用new,和delete操作,那它们的到底怎样工作的呢?
比如,我们创建一个string对象sp
string * sp = new string("initialized");
首先,表达式会调用标准库中函数operator new 分配足够的未类型化的raw内存,接着,调用placement new操作构建对象,最后返回指向构建对象的指针。
当 delete sp; 时候,会先调用sp的析构函数,释放对象,最后会调用operator delete释放内存。
下面是operator new和operator delete的函数定义:
void *operator new(size_t); // allocate an object
void *operator new[](size_t); // allocate an array
void *operator delete(void*); // free an object
void *operator delete[](void*); // free an array
定位new表示在式在已分配的内存中构造对象,它类似于allocator类中的construct。它的语法如下:
new (place_address) type
new (place_address) type (initializer-list)
new (first_free) T(t);
type (initializer-list)其实就是类型的一个构造函数。
下面是采用operator new, operator delete以及定位new实现的myVector代码:Code
1
2 #include "stdafx.h"
3 #include <iostream>
4 #include <memory>
5 using namespace std;
6
7 template <class T> class myVector
8 {
9 public:
10 typedef T* iterator;//定义T*别名作为迭代器
11 myVector(): elements(0), first_free(0), end(0) { };
12 ~myVector();
13 void push_back(const T&);
14 size_t size() const { return first_free - elements; }//得到myVector中元素个数
15 size_t capacity() const { return end - elements; } //得到myVector的容量
16 // . . .
17 T& operator[](size_t n) { return elements[n]; }
18 const T& operator[](const size_t n) const { return elements[n]; }
19 void reserve(const size_t n);
20 void resize(const size_t n);
21 void resize(const size_t n, const T& t);//两个resize版本
22 iterator Begin() { return elements;}
23 iterator End() {return first_free;}
24 private:
25 void reallocate(); // 重新分配内存,以容纳更多的元素,内存分配策略在这个函数中实施
26 T* elements; // 指向行列式中的第一个元素
27 T* first_free; // 指向行列式中第一个空的元素(未赋值)
28 T* end; // 指向行列式的尾部
29 // . . .
30 };
31
32 #include <algorithm>
33
34
35 template <class T> myVector<T>::~myVector()
36 {
37 //析构函数释放内存
38
39
40 //通过显示调用T类型的析构函数释放内存
41 for (T *p = first_free; p != elements; /*empty*/ )
42 (--p)->~T();
43
44 //通过operator delete释放内存
45 if (elements)
46 operator delete[] (elements);
47 }
48
49 using std::max;
50 using std::uninitialized_copy;
51 template <class T> void myVector<T>::reallocate()
52 {
53 //每次分配2倍元素大小的空间
54 std::ptrdiff_t size = first_free - elements;
55 std::ptrdiff_t newcapacity = 2 * max(size, 1);
56
57 //用operator new分配内存,注意它分配的是指向void的指针,要进行类型转化
58 T* newelements = static_cast<T*>(operator new[](newcapacity*sizeof(T)));
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 (--p)->~T();
66
67 // elments不为空,释放内存
68 if (elements)
69 operator delete[] (elements);
70
71 // 调整三个指针变量位置
72 elements = newelements;
73 first_free = elements + size;
74 end = elements + newcapacity;
75 }
76
77 template <class T> void myVector<T>::reserve(const size_t n)
78 {
79 if(n>capacity())//小于容量直接忽略掉
80 {
81 std::ptrdiff_t size = first_free - elements;
82 T* newelements = static_cast<T*>(operator new[](n*sizeof(T)));//alloc.allocate(n);
83 uninitialized_copy(elements, first_free, newelements);
84
85 for (T *p = first_free; p != elements; /*empty*/ )
86 (--p)->~T();
87
88 // elments不为空,释放内存
89 if (elements)
90 operator delete[] (elements);
91 elements = newelements;
92 first_free = elements + size;
93 end = elements + n;
94
95 }
96 }
97
98 template <class T> void myVector<T>::resize(const size_t n)
99 {
100 size_t size = first_free - elements;
101 size_t capacity = end -elements;
102
103 if( n > capacity)
104 {
105 reallocate();//分配更多空间并拷贝元素
106 unintialized_fill(first_free, elements + n, T());//调用T的默认构造函数
107 }
108 else (n > size)
109 {
110 unintialized_fill(first_free, elements + n, T());
111 }
112 else
113 {
114 for(T *p = first_free; p != elements + n;)
115 {
116 (--p)->~T();
117 }
118 first_free = elements + n;
119 }
120 }
121
122 template <class T> void myVector<T>::resize(const size_t n, const T& t)
123 {
124 size_t size = first_free - elements;
125 size_t capacity = end -elements;
126
127 if( n > capacity)
128 {
129 reallocate();
130 unintialized_fill(first_free, elements + n, t);
131 }
132 else (n > size)
133 {
134 unintialized_fill(first_free, elements + n, t);
135 }
136 else
137 {
138 for(T *p = first_free; p != elements + n;)
139 {
140 (--p)->~T();
141 }
142 first_free = elements + n;
143 }
144 }
145
146 //在myVector中插入一个元素
147 template <class T> void myVector<T>::push_back(const T& t)
148 {
149 // 没有空间了,end指向可使用内存的下一个位置
150 if (first_free == end)
151 reallocate();
152 // 在first_free位置构造t对象,调用拷贝构造函数
153 new (first_free) T(t);
154 //指针递增
155 ++first_free;
156 }
157
158 int main()
159 {
160 myVector<int> vi;
161 vi.reserve(100);//可以避免多次分配内存
162
163 for (int i = 0; i != 10; ++i)
164 {
165 vi.push_back(i);
166 cout << vi[i] << endl;
167 }
168
169 for (int i = 0; i != 10; ++i)
170 cout << vi[i] << endl;
171
172 //迭代器的使用
173 for(myVector<int>::iterator it = vi.Begin(); it != vi.End(); ++it)
174 cout << *it <<endl;
175 return 0;
176 }
177