简化版vector
程序员文章站
2022-03-01 23:21:33
...
参考书上敲了一个简化版的vector,这里的简化主要是指没有用模板去实现vector,而仅以基于string的vector这个范例来演示其内部的内存分配原理:
实现的功能有以下几点:
- 实现了预先保留空间,其内存分配策略为扩大两倍容量。
- 基于allocator实现了申请内存和初始化对象的分离。
- 使用move函数实现string的移动构造。
待实现的功能:
- 模板技术
- 引用计数
- 内部其他方法
代码如下:
#include <iostream>
#include <vector>
#include <allocators>
#include <string>
class MyVector {
public:
MyVector():first(nullptr),first_free(nullptr),last(nullptr){}
MyVector(const MyVector&v) {
pair<string*, string*> pir = alloc_copy(v.begin(), v.end());
first = pir.first;
first_free =last= pir.second;
};
MyVector &operator=(const MyVector&v) {
free();
auto data = alloc_copy(v.begin(), v.end());
first = data.first;
first_free = data.second;
return *this;
};
~MyVector() { free(); };
void push_back(const string& s) {
check_alloc();
alloc.construct(first_free++, s);
};
size_t size() const { return first_free - first; };
size_t capacity() const { return last - first; };
string *begin() const { return first; };
string *end() const { return first_free; };
private:
static allocator<string> alloc;
//allocator<string> alloc;
void check_alloc() {
//检查容器是否已满
if (size() == capacity())
reallocate();
}
//拷贝构造一段
pair<string*,string*> alloc_copy(string*begin, string*end) {
auto data = alloc.allocate(end - begin);
return make_pair(data, uninitialized_copy(begin, end, data));
}
//析构并释放所有内存
void free() {
//不能给deallocate传递空指针
if (first) {
for (auto p = first; p != first_free;) {
alloc.destroy(p++);
}
alloc.deallocate(first, last - first);
}
};
void reallocate() {
//注意size为0的情况
int new_alloc = size()?capacity() * 2:1;
string *data_start = alloc.allocate(new_alloc);
string *temp_start = data_start;
string *temp_first = first;
for (size_t i = 0; i < size(); i++) {
alloc.construct(temp_start++, move(*temp_first++));
}
free();
first = data_start;
first_free = temp_start;
last = data_start + new_alloc;
}
string *first;
string *first_free;
string *last;
};
该类的私有属性:
string *first 是指向动态数组头部的指针
string *first_free 是指向动态数组已使用空间之后的第一个指针(即end)
string *last 是指向动态数组可使用空间之后的一个指针