欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

简化版vector

程序员文章站 2022-03-01 23:21:33
...

参考书上敲了一个简化版的vector,这里的简化主要是指没有用模板去实现vector,而仅以基于string的vector这个范例来演示其内部的内存分配原理:

实现的功能有以下几点:

  1. 实现了预先保留空间,其内存分配策略为扩大两倍容量。
  2. 基于allocator实现了申请内存和初始化对象的分离。
  3. 使用move函数实现string的移动构造。

待实现的功能:

  1. 模板技术
  2. 引用计数
  3. 内部其他方法

代码如下:

#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 是指向动态数组可使用空间之后的一个指针

相关标签: vector