编程语言
首页 > 编程语言> > vector源码解析

vector源码解析

作者:互联网

1、vector源码解释与测试

调试环境采用的是VS2015,大家可以选择自己合适的编译环境去调试。

myVector.h

#ifndef MY_VECTOR_H
#define MY_VECTOR_H
#define _SCL_SECURE_NO_WARNINGS 

#include <memory>
#include <iostream>
#include <algorithm>
template <class T, class Alloc = std::allocator<T>>
class myVector
{
public:
	//vector的嵌套类型
	typedef T						value_type;
	typedef value_type*				iterator;
	typedef const value_type*		const_iterator;
	typedef value_type&				reference;
	typedef value_type*				pointer;
	typedef	size_t					size_type;
	typedef ptrdiff_t				difference_type; //表示两个迭代器之间的距离 ,c++内置定义 typedef int ptrdiff_t;
protected:
	std::allocator<value_type> _alloc;  //空间分配器,这里使用stl标准写法,而不是sgi标准写法
	iterator _start;					//数组的首元素
	iterator _end;					//目前使用空间的尾
	iterator _end_of_storage;			//目前可用空间的尾
public:
	myVector() :_start(0), _end(0), _end_of_storage(0) {}//默认构造函数
	myVector(size_type n, const T& value);
	myVector(size_type n);
	myVector(iterator first, iterator last);
	myVector(const myVector& v);			//复制构造函数
	myVector& operator=(const myVector& rhs);  //赋值操作符函数
	~myVector() { _destroy(); }


	iterator begin() { return _start; }
	iterator end() { return _end; }
	const_iterator cbegin() const { return _start; }    //常量迭代器
	const_iterator cend() const { return _end; }

	size_type size() { return size_type(end() - begin()); }  //注意转换成size_t类型
	size_type capacity() { return size_type(_end_of_storage - begin()); }
	bool empty() { return begin() == end(); }
	void swap(myVector &other);


	reference front() { return *begin(); }
	reference back() { return *(end() - 1); }
	reference operator[] (size_type n) { return *(begin() + n); }           //重载[],这样可以用a[n]进行访问元素

																			//删除数组中的元素,并且释放内存

	void insert_aux(iterator positon, const T& x);  //一个插入辅助的函数,在向量为满的时候用到
	void push_back(const T& value);
	void pop_back();
	void insert(iterator position, size_type n, const T& x);

	iterator erase(iterator position);
	iterator erase(iterator first, iterator last);  //删除[first,last)的元素
	void clear() { erase(begin(), end()); }
private:

	void _destroy();   //删除数组中的元素,并且释放内存

};



template <class T, class Alloc = std::allocator<T>>
myVector<T, Alloc>::myVector(size_type n, const T& value) {
	_start = _alloc.allocate(n);						 //调用配置器函数分配内存
	std::uninitialized_fill(_start, _start + n, value);  //调用c++内置函数进行初始化
	_end = _end_of_storage = _start + n;                 //修改迭代器的指针
}
//构造函数n 个0
template <class T, class Alloc = std::allocator<T>>
myVector<T, Alloc>::myVector(size_type n) {
	_start = _alloc.allocate(n);
	std::uninitialized_fill(_start, _start + n, 0);
	_end = _end_of_storage = _start + n;
}
//
template <class T, class Alloc = std::allocator<T>>
myVector<T, Alloc>::myVector(iterator first, iterator last) {
	_start = _alloc.allocate(last - first);  //分配空间
	_end = _end_of_storage = std::uninitialized_copy(first, last, _start);
}
//
template <class T, class Alloc = std::allocator<T>>
myVector<T, Alloc>::myVector(const myVector& v) {
	size_type n = v.cend() - v.cbegin();
	_start = _alloc.allocate(n);    //分配空间
	_end = _end_of_storage = std::uninitialized_copy(v.cbegin(), v.cend(), _start);
}
//
template <class T, class Alloc = std::allocator<T>>
void myVector<T, Alloc>::swap(myVector &other) {
	std::swap(_start, other._start);
	std::swap(_end, other._end);
	std::swap(_end_of_storage, other._end_of_storage);
}
//
template <class T, class Alloc = std::allocator<T>>
myVector<T, Alloc> &myVector<T, Alloc>::operator=(const myVector &rhs) {
	if (this == &rhs)
		return *this;
	size_type n = rhs.cend() - rhs.cbegin();
	_start = _alloc.allocate(n);
	_end = _end_of_storage = std::uninitialized_copy(rhs.cbegin(), rhs.cend(), _start);
}
//

template <class T, class Alloc = std::allocator<T>>

void myVector<T, Alloc>::insert(iterator position, size_type n, const T& x) {
	if (n >= 0) {
		if (_end_of_storage - _end >= n) {   //剩余空间够用,分两种情况
			T x_copy = x;
			const size_type elem_after = _end - position;   //计算插入点之后的元素个数
			iterator old_end = _end;
			if (elem_after > n) {
				uninitialized_copy(_end - n, _end, _end);
				_end = _end + n;        //将尾端后移
				copy_backward(position, old_end - n, old_end);
				fill(position, position + n, x_copy);
			}
			else {                      //要插入的元素大于等于插入点之后元素
				uninitialized_fill_n(_end, n - elem_after, x_copy);
				_end += n - elem_after;
				uninitialized_copy(position, old_end, _end);
				_end += elem_after;
				fill(position, old_end, x_copy);
			}
		}
		else {            //如果剩余空间不足
			const size_type old_size = size();
			const size_type len = old_size + max(old_size, n);
			iterator new_start = _alloc.allocate(len);
			iterator new_end = new_start;
			new_end = uninitialized_copy(_start, position, new_start);   //将position之前的元素复制到新容器
			new_end = uninitialized_fill_n(new_end, n, x);    //插入元素
			new_end = uninitialized_copy(position, _end, new_end);
			_destroy();   //调用成员函数进行释放空间
						  //重新调整迭代器,使其指向新的位置
			_start = new_start;
			_end = new_end;
			_end_of_storage = new_start + len;
		}
	}
}
//
template <class T, class Alloc = std::allocator<T>>
void myVector<T, Alloc>::insert_aux(iterator positon, const T& x) {
	if (_end != _end_of_storage) {

	}
	else {
		const size_type old_size = size();                    //需要注意,如果开始长度为0
		const size_type len = old_size ? 2 * old_size : 1;    //则配置长度1,否则,加倍
		iterator new_start = _alloc.allocate(len);            //重新分配空间
		iterator new_end = new_start;

		new_end = uninitialized_copy(_start, positon, new_start);   //对于push_back来说position=_end,将其拷贝出来
		_alloc.construct(new_end, x);                     //插入元素
		++new_end;
		new_end = uninitialized_copy(positon, _end, new_end);     //将插入点后的元素也拷贝过来

		_destroy();                    //执行自定义函数
									   //调整迭代器,指向新的指针

									   //重新调整迭代器,使其指向新的位置
		_start = new_start;
		_end = new_end;
		_end_of_storage = new_start + len;


	}
}
//
template <class T, class Alloc = std::allocator<T>>
void myVector<T, Alloc>::push_back(const T& value) {
	if (_end != _end_of_storage) {        //如果还有剩余的空间
		_alloc.construct(_end, value);        //在_end处调用配置器插入value
		++_end;                               //迭代器后移
	}
	else
		insert_aux(end(), value);                //如果空间已满		
}
//
template <class T, class Alloc = std::allocator<T>>
void myVector<T, Alloc>::pop_back() {
	--_end;               //这里要注意的是,删除尾部,要让_end先移动到最后一个元素
	_alloc.destroy(_end);
}
//
template <class T, class Alloc = std::allocator<T>>
typename myVector<T, Alloc>::iterator myVector<T, Alloc>::erase(iterator position) {
	if (position + 1 != end())   //也就是说要删除的这个元素不是最后一个元素
		copy(position + 1, end(), position);
	--_end;
	_alloc.destroy(_end);
	return position;
}
//
template <class T, class Alloc = std::allocator<T>>
typename myVector<T, Alloc>::iterator myVector<T, Alloc>::erase(iterator first, iterator last) {
	difference_type left = _end - last;
	std::copy(last, _end, first);         //first last avail 向前迁移元素
	iterator it(first + left);
	while (_end != it)                   //需要析构,有可能不需要析构,这要看在last后元素与删除元素的比较
		_alloc.destroy(--_end);
	return first;
}


template <class T, class Alloc = std::allocator<T>>
void myVector<T, Alloc>::_destroy() {
	//先执行析构函数
	if (_start)
	{
		iterator it(_end); //初始
		while (it != _start)
			_alloc.destroy(--it);
	}

	//释放内存
	_alloc.deallocate(_start, _end_of_storage - _start);
	_start = _end_of_storage = _end = NULL;
}
#endif

myVector_Demo.cpp

#include "myVector.h"
#include <string>
#include <vector>
using namespace std;
int main()
{
	myVector<float>v;
	cout << "测试默认构造函数" << endl;
	cout << v.size() << " " << v.capacity() << endl;
	cout << "测试构造函数,构造10个1元素" << endl;
	myVector<int> v1(10, 1);
	for (int i = 0; i < v1.size(); i++)
		cout << v1[i] << "  ";			 //操作符重载[]成功   
	cout << endl;
	
	
	cout << "得到头和尾的值" << endl;
	cout << v1.front() << "  " << v1.back() << endl;  //测试函数
	cout << endl;
	cout << "测试复制构造函数" << endl;
	myVector<int> vcopy(v1);
	for (int i = 0; i < vcopy.size(); i++)
		cout << vcopy[i] << "  ";
	cout << endl;
	
	
	cout << "测试赋值操作符" << endl;
	myVector<int>vv;
	vv = v1;
	for (int i = 0; i < vv.size(); i++)
		cout << vv[i] << "  ";
	cout << endl;
	
	

	cout << "测试构造函数,构造n个0元素" << endl;
	myVector<float>v2(10);
	for (int i = 0; i < v2.size(); i++)
		cout << v2[i] << "  ";
	
	cout << "测试是否为空" << endl;
	cout << boolalpha << v2.empty() << endl;
	cout << "测试push_back()" << endl;
	v2.push_back(3);
	cout << v2.size() << "  " << v2.capacity() << "  " << v2[1] << endl;
	cout << "测试pop_back()" << endl;
	v2.pop_back();
	cout << v2.size() << "  " << v2.capacity() << "  " << v2[10] << endl;
	cout << "测试erase(fisrt,last)" << endl;
	for (int i = 0; i < v2.size(); i++) {
		v2[i] += i; cout << v2[i] << "  ";
	}
	
	cout << endl;
	v2.erase(v2.begin(), v2.begin() + 2);    //从开始,删除两个元素
	for (int i = 0; i < v2.size(); i++)
		cout << v2[i] << "  ";
	cout << endl;
	cout << "测试erase(positon)" << endl;
	v2.erase(v2.begin() + 2);
	for (int i = 0; i < v2.size(); i++)
		cout << v2[i] << "  ";
	cout << endl;

	
	//测试重要的函数insert()
	
	cout << "测试insert(iterator positon, size_type n, const T& x)" << endl;
	myVector<string>vec(5, "test");
	for (int i = 0; i < vec.size(); i++)
		cout << vec[i] << "  ";
	cout << endl;
	vec.insert(vec.begin() + 2, 7, "program");   //加入7个相同字符
	for (int i = 0; i < vec.size(); i++)
		cout << vec[i] << "  ";
	cout << endl;
	cout << vec.size() << "  " << vec.capacity() << endl;

	cout << "测试迭代器" << endl;
	myVector<string> str(10, "test");
	auto it = str.begin();          //auto位c++11关键字,判断类型
	for (; it != str.end(); ++it)
		cout << *it << " ";
	cout << endl;

	cout << "使矩阵给容器赋初值" << endl;
	int a[] = { 1,2,3,4,5,6,7,8,9 };
	myVector<int> v4(a, a + sizeof(a) / sizeof(a[0]));
	for (int i = 0; i < v4.size(); i++)
		cout << v4[i] << "  ";
	cout << endl;

	
	system("pause");
	return 0;
}
#pragma once

小麦大大 发布了159 篇原创文章 · 获赞 56 · 访问量 9万+ 私信 关注

标签:myVector,end,iterator,start,vector,解析,type,源码,size
来源: https://blog.csdn.net/qq_35433716/article/details/104593208