zoukankan      html  css  js  c++  java
  • 【STL源码剖析读书笔记】自己实现vector之MyVector

    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;
    }

  • 相关阅读:
    《面向模式的软件体系结构1模式系统》读书笔记(7) 通信
    《面向模式的软件体系结构2用于并发和网络化对象模式》读书笔记(5) 截取器
    Enum variable is used in switch sentencejava Anny
    How to create a dynamic range source(转) Anny
    Managing Range Names in Excel 2010(转) Anny
    Mixed Content Handling Issue on IE7/8 Anny
    How to resolve "skip non existing resourceDirectory" when using "mvn test" Anny
    Install chinese input method in Ubuntu12.04 Anny
    IDL(International Date Line) Anny
    Web Accessibility508(转) Anny
  • 原文地址:https://www.cnblogs.com/ruan875417/p/4558291.html
Copyright © 2011-2022 走看看