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

【STL源码剖析读书笔记】自己实现vector之MyVector

程序员文章站 2022-07-12 18:07:56
...

MyVector.h

#ifndef MY_VECTOR_H
#define MY_VECTOR_H

#define _SCL_SECURE_NO_WARNINGS //为了防止在VS2013中报错
#include<cstddef> //ptrdiff_t
#include<memory>

template<typename T>
void destroy(T* ptr){
	ptr->~T();
}
template<typename ForwardIterator>
void destroy(ForwardIterator first, ForwardIterator last){
	for (; first != last; ++first)
		destroy(&*first);
}

template<typename T>
class MyVector{
public:
	//嵌套型别定义
	typedef T value_type;
	typedef T* pointer;
	typedef const T* const_pointer;
	typedef T* iterator;
	typedef const T* const_iterator;
	typedef T& reference;
	typedef const T& const_reference;
	typedef size_t size_type;
	typedef ptrdiff_t difference_type;
protected:
	iterator start; //目前使用空间的头
	iterator finish;//目前使用空间的尾
	iterator end_of_storage;//目前可用空间的尾
	std::allocator<T> alloc; //空间分配器
public:
	MyVector(); //默认构造函数
	MyVector(size_type n, const T& value);//构造函数
	MyVector(iterator first, iterator last);//构造函数
	~MyVector(); //析构函数
	MyVector(MyVector& vec); //拷贝构造函数
	MyVector& operator=(MyVector& vec); //拷贝赋值运算符
public:
	iterator begin(){ return start; }
	const_iterator begin() const { return start; }
	iterator end(){ return finish; }
	const_iterator end() const { return finish; }

	size_type size() const { return (size_type)(finish - start); }
	size_type capacity() const { return (size_type)(end_of_storage - start); }
	bool empty() const { return start == finish; }

	reference operator[](size_type n){ return *(begin() + n); }
	const_reference operator[](size_type n) const { return *(begin() + n); }
	reference front() { return *begin(); }
	const_reference front() const { return *begin(); }
	reference back(){ return *(end() - 1); }
	const_reference back() const { retunr *(end() - 1); }

	void push_back(const T& value);
	void pop_back();
	void insert(iterator position,size_type n,const T& value);
	iterator erase(iterator position);
	iterator erase(iterator first,iterator last);
	void resize(size_type new_size);
	void resize(size_type new_size, const T& value);
	void reserve(size_type new_size);
	void clear();
private:
	void free();
	void reallocate();
};
//默认构造函数
template<typename T>
MyVector<T>::MyVector():start(nullptr),finish(nullptr),end_of_storage(nullptr){}
//构造函数
template<typename T>
MyVector<T>::MyVector(size_type n, const T& value){
	start=alloc.allocate(n);
	finish = end_of_storage = start + n;
	for (iterator it = start; it != finish; ++start)
		alloc.construct(it, value);
}
//构造函数
template<typename T>
MyVector<T>::MyVector(iterator first, iterator last){
	size_type n = (size_type)(last - first);
	start = alloc.allocate(n);
	finish = end_of_storage = start + n;
	std::uninitialized_copy(first, last, start);
}
//析构函数
template<typename T>
MyVector<T>::~MyVector(){
	free();
}
template<typename T>
void MyVector<T>::free(){
	destroy(start, finish);
	alloc.deallocate(start, capacity());
}
//拷贝构造函数
template<typename T>
MyVector<T>::MyVector(MyVector& vec){
	start = alloc.allocate(vec.size());
	finish = end_of_storage = start + vec.size();
	std::uninitialized_copy(vec.begin(), vec.end(), start);
}
//拷贝赋值运算符
template<typename T>
MyVector<T>& MyVector<T>::operator=(MyVector& vec){
	if (vec != *this){
		iterator new_start = alloc.allocate(vec.size());
		std::uninitialized_copy(vec.begin(), vec.end(), new_start);
		size_type old_size = size();
		size_type old_capacity = capacity();
		free();
		start = new_start;
		finish = start + old_size;
		end_of_storage = start + old_capacity;
	}
	return *this;
}
//reallocate()
template<typename T>
void MyVector<T>::reallocate(){
	size_type new_size = size() ? size() * 2 : 1;
	iterator new_start = alloc.allocate(new_size);
	iterator new_finish=std::uninitialized_copy(start, finish, new_start);
	free();
	start = new_start;
	finish = new_finish;
	end_of_storage = start + new_size;
}
//push_back(const T& value)
template<typename T>
void MyVector<T>::push_back(const T& value){
	if (size() == capacity())
		reallocate();
	alloc.construct(finish++, value);
}
//pop_back()
template<typename T>
void MyVector<T>::pop_back(){
	alloc.destroy(--finish);
}
//insert(iterator position, size_type n, const T& value)
template<typename T>
void MyVector<T>::insert(iterator position, size_type n, const T& value){
	if (n <= (size_type)(capacity() - size())){
		if (n > (size_type)(finish - position)){
			std::uninitialized_fill(finish, finish + n - (size_type)(finish - position),value);
			std::uninitialized_copy(position, finish, position + n);
			std::uninitialized_fill(position, finish, value);
		}
		else{
			std::copy_backward(position, finish, finish + n);
			std::uninitialized_fill_n(position, n, value);
		}
		finish += n;
	}
	else{
		size_type new_size = size() + (size() > n ? size() : n);
		iterator new_start = alloc.allocate(new_size);
		iterator new_finish = std::uninitialized_copy(start, position, new_start);
		new_finish=std::uninitialized_fill_n(new_finish, n, value);
		new_finish = std::uninitialized_copy(position, finish, new_finish);
		free();
		start = new_start;
		finish = new_finish;
		end_of_storage = start + new_size;
	}
}
//erase(iterator position)
template<typename T>
typename MyVector<T>::iterator MyVector<T>::erase(iterator position){
	if (position+1!=finish)
		std::uninitialized_copy(position + 1, finish, position);
	destroy(--finish);
	return position;
}
//erase(iterator first, iterator last)
template<typename T>
typename MyVector<T>::iterator MyVector<T>::erase(iterator first, iterator last){
	size_type n = (size_type)(last - first);
	std::uninitialized_copy(last, finish, first);
	destroy(finish - n, finish);
	finish = finish - n;
	return first;
}
//resize(size_type new_size)
template<typename T>
void MyVector<T>::resize(size_type new_size){
	resize(new_size, T());
}
//resize(size_type new_size, const T& value)
template<typename T>
void MyVector<T>::resize(size_type new_size, const T& value){
	if (new_size > size())
		insert(finish, new_size - size(), value);
	else
		erase(begin() + new_size, finish);
}
//reserve(size_type new_size)
template<typename T>
void MyVector<T>::reserve(size_type new_size){
	if (new_size > capacity()){
		iterator new_start = alloc.allocate(new_size);
		size_t old_size = size();
		std::uninitialized_copy(start, finish, new_start);
		free();
		start = new_start;
		finish = start + old_size;
		end_of_storage = start + new_size;
	}
}
//clear()
template<typename T>
void MyVector<T>::clear(){
	erase(start, finish);
}

#endif
main.cpp
#include "MyVector.h"
#include<iostream>
using namespace std;

int main(){

	MyVector<int> vec;
	for (int i = 0; i != 10; ++i)
		vec.push_back(i);  //push_back()

	MyVector<int>::iterator it;
	MyVector<int> vec2(vec); //拷贝构造
	for (it = vec2.begin(); it != vec2.end(); ++it) //begin(),end()
		cout << *it << " "; //0 1 2 3 4 5 6 7 8 9
	cout << endl;

	MyVector<int> vec3 = vec; //拷贝赋值运算符
	for (it = vec3.begin(); it != vec3.end(); ++it)
		cout << *it << " "; //0 1 2 3 4 5 6 7 8 9
	cout << endl;

	for (it = vec.begin(); it != vec.end(); ++it)
		cout << *it << " ";   //0 1 2 3 4 5 6 7 8 9
	cout << endl;
	cout << "size:" << vec.size() << endl; //10 size()
	cout << "capacity:" << vec.capacity() << endl; //16 capacity()
	vec.reserve(10); //reserve()
	cout << "capacity:" << vec.capacity() << endl; //16
	vec.reserve(30);//reserve()
	cout << "capacity:" << vec.capacity() << endl; //30

	vec.pop_back(); //pop_back()
	for (size_t i = 0; i <vec.size(); ++i)
		cout << vec[i] << " ";//0 1 2 3 4 5 6 7 8 
	cout << endl;

	cout << "front:" << vec.front() << endl; //0 front()
	cout << "back:" << vec.back() << endl; //8 back()

	vec.insert(vec.begin() + 5, 3, 10);  //insert()
	for (const auto& c : vec)
		cout << c << " ";//0 1 2 3 4 10 10 10 5 6 7 8 
	cout << endl;

	vec.erase(vec.begin() + 2, vec.begin() + 5); //erase()
	for (it = vec.begin(); it != vec.end(); ++it)
		cout << *it << " ";//0 1 10 10 10 5 6 7 8 
	cout << endl;
	cout << "size:" << vec.size() << endl; //9

	vec.resize(5);  //resize()
	for (it = vec.begin(); it != vec.end(); ++it)
		cout << *it << " ";//0 1 10 10 10
	cout << endl;
	cout << "size:" << vec.size() << endl; //5

	vec.resize(10);
	for (it = vec.begin(); it != vec.end(); ++it)
		cout << *it << " ";//0 1 10 10 10 0 0 0 0 0
	cout << endl;
	cout << "size:" << vec.size() << endl; //10

	vec.clear();  //clear()
	cout << (vec.empty() ? "vector empty" : "vector not empty") << endl; //empty

	system("pause");
	return 0;
}