vector第四步修炼之道
来源:互联网 发布:绘制图纸软件 编辑:程序博客网 时间:2024/06/01 09:08
在使用系统中自带的STL库时,我们会使用迭代器来访问容器中的元素。那么《vector第二步修炼之道》和《vector第三步修炼之道》之中,我们均是使用自定义vector 类的show() 函数来进行访问的。当然,我们也是可以自定义迭代器来实现元素的访问。
准备资料:
首先,看如下的代码:
void show(vector<int>& vec){ vector<int>::iterator it = vec.begin(); for (; it != vec.end(); it++) { cout << *it << " "; } cout << endl;}
我们可以看到模板类vector,其中迭代器在模板类中的作用域内,那么我们可以做下面几件事:
(1)自定义迭代器作为模板类的内置类,并定义构造函数;
(2)需要重载的运算符:!=,前置++,*;
(3)需要定义模板类的begin() 和end() 方法
代码书写:
#pragma once#include<iostream>using namespace std;template<typename T>class myAllocator{public: //allocate : 开辟内存的 malloc ptmalloc T* allocate(size_t size) { return (T*)operator new(sizeof(T)*size); } //deallocate : 释放内存的 free void deallocate(void *p) { operator delete(p); } void construct(T* _P, const T& _V) { new (_P) T(_V); } //destroy : 专门析构的 void destroy(T* _P) { _P->~T(); }};template <typename E, typename A = myAllocator<E>>class vector{public: //默认构造函数,所有成员都给默认的零值 vector(int initialsize = 0, const A &a = A()); //vector(int initialsize , const A &a ); //num:初始元素的个数,value表示初始元素的值 vector(int num, E value); //用[first, last)区间的元素初始化当前容器 vector(E *first, E *last); //析构函数 ~vector(); //拷贝构造函数 vector(const vector&src); //赋值运算符的重载函数 void operator=(const vector&src); //向容器的末尾添加新元素value,若增长内存,调用resize函数 void push_back(const E &value); //删除容器末尾的元素 void pop_back(); //查找某个元素的地址 E* getpos(int val); //向指定位置pos插入新元素value,若增长内存,调用resize函数 void insert(E *pos, const E &value); //删除指定位置的元素 void erase(E *pos); //打印容器有效元素值的函数 void show()const; //判断容器是否空 bool empty()const; //判断容器是否满 bool full()const; //获取容器元素个数 int size() const;//自定义迭代器类 class Iterator { public: Iterator(E *ptr = NULL) :ptr(ptr) {} //访问元素 E& operator*() { return *ptr; } E& operator[](int index) { return ptr[index]; } //重载运算符前置++ void operator++() //void 类型,无引用 { ++ptr; } //重载运算符前置!= bool operator!=(const Iterator &iter) { return ptr != iter.ptr; } //重载运算符前置- int operator-(const Iterator &iter) { return ptr - iter.ptr; } private: E *ptr; }; //获取容器首元素地址 Iterator begin() { return Iterator(_first); } //获取容器末尾元素地址 Iterator end() { return Iterator(_first+_last); }private: //内存增长函数,按原有容量的两倍增长 void resize() { if (_end == 0)//默认构造vector; { _end = 1; _first = _allocator.allocate(_end); } else { E *_newfirst = _allocator.allocate(_end * 2); for (int i = 0; i < _end; i++) { _allocator.construct(_newfirst + i, _first[i]); _allocator.destroy(_first + i); } _end *= 2; _allocator.deallocate(_first); _first = _newfirst; } } A _allocator;//存储用户指定的空间配置器 E *_first; //存储放入容器的元素 int _end; //_element数组的总容量 int _last; //_element有效元素的个数};//默认构造函数,所有成员都给默认的零值template <typename E, typename A = myAllocator<E>>vector<E, A>::vector(int initialsize = 0, const A &a = A()) :_last(0), _end(initialsize), _allocator(a){ if (initialsize == 0) { _first = NULL; } else { _first = _allocator.allocate(_end); }}//num:初始元素的个数,value表示初始元素的值template <typename E, typename A = myAllocator<E>>vector<E, A>::vector(int num, E value) :_end(num), _last(num){ _first = _allocator.allocate(num); for (int i = 0; i < _end; i++) { _allocator.construct(_first + i, value); }}////用[first, last)区间的元素初始化当前容器template <typename E, typename A = myAllocator<E>>vector<E, A>::vector(E *first, E *last){ int size = *last - *first; _first = _allocator.allocate(size); _end = _last = size; for (int i = 0; i < size; i++) { _allocator.construct(_first + i, (*first)++); }}//析构函数template <typename E, typename A = myAllocator<E>>vector<E, A>::~vector(){ if (_first != NULL) { for (int i = 0; i < _last; i++) { _allocator.destroy(_first + i); } _allocator.deallocate(_first); _first = NULL; _end = 0; _last = 0; }}//拷贝构造函数template <typename E, typename A = myAllocator<E>>vector<E, A>::vector(const vector &src){ _end = src._end; //_first = new E[_end]; _first = _allocator.allocate(_end); _last = src._last; for (int i = 0; i < _last; i++) { _allocator.construct(_first + i, (src._first)[i]); }}//赋值运算符的重载函数template <typename E, typename A = myAllocator<E>>void vector<E, A>::operator=(const vector &src){ if (this == &src) { return; } if (_first != NULL) { for (int i = 0; i < _last; i++) { _allocator.destroy(_first + i); } _allocator.deallocate(_first); } _end = src._end; _first = _allocator.allocate(_end); _last = src._last; for (int i = 0; i < _last; i++) { _allocator.construct(_first + i, (src._first)[i]); }}//向容器的末尾添加新元素value,若增长内存,调用resize函数template <typename E, typename A = myAllocator<E>>void vector<E, A>::push_back(const E &value){ if (full()) { resize(); } _allocator.construct(_first + _last, value); _last++;}//删除容器末尾的元素template <typename E, typename A = myAllocator<E>>void vector<E, A>::pop_back(){ if (!empty()) { _last--; _allocator.destroy(_first + _last); }}// vector 元素的位置template <typename E, typename A = myAllocator<E>>E* vector<E, A>::getpos(int val){ for (int i = 0; i < _end; i++) { if (_first[i] == val) { return &(_first[i]); } } return NULL;}//向指定位置pos插入新元素value,若增长内存,调用resize函数template <typename E, typename A = myAllocator<E>>void vector<E, A>::insert(E *pos, const E &value){ int index = pos - _first; if (index<0 || index>_last) { printf("error"); return; } if (full()) { resize(); } if (index < _last) { for (int i = _last; i > index; --i) { _allocator.construct(_first + i, _first[i - 1]); _allocator.destroy(_first + i - 1); } } _allocator.destroy(_first + index); _allocator.construct(_first + index, value); _last++;}//删除指定位置的元素template <typename E, typename A = myAllocator<E>>void vector<E, A>::erase(E *pos){ int index = pos - _first; if (index<0 || index>_last) { printf("error"); return; } if (!empty()) { for (int i = index; i < _last - 1; i++) { _allocator.destroy(_first + i); _allocator.construct(_first + i, _first[i + 1]); } _last--; _allocator.destroy(_first + _last); }}//打印容器有效元素值的函数template <typename E, typename A = myAllocator<E>>void vector<E, A>::show()const{ if (_first != NULL) { for (int i = 0; i < _last; i++) { cout << _first[i]; } cout << endl; }}//判断容器是否空template <typename E, typename A = myAllocator<E>>bool vector<E, A>::empty()const{ if (_last == 0) { return true; } else { return false; }}//判断容器是否满template <typename E, typename A = myAllocator<E>>bool vector<E, A>::full()const{ if (_last == _end) { return true; } else { return false; }}//获取容器元素template <typename E, typename A = myAllocator<E>>int vector<E, A>::size()const{ return _last;}
测试函数
#include<iostream>//#include "vectorAllocate.h"#include "vectorAllocateIterator.h"using namespace std;int main(){ /*******vectorAllocateIterator的使用********/ myAllocator<int> alloc; vector<int, myAllocator<int>> vec1(10, alloc); vec1.show(); vector<int, myAllocator<int>> vec2(10, 1); vec2.show(); vector<int>::Iterator iter = vec2.begin(); for (; iter != vec2.end(); ++iter) { cout << *iter << " "; } cout << endl; vector<int>::Iterator iter2 = vec2.begin(); //此时iter已经指向容器最后一个元素了,故需要重新定义 for (int i = 0; i < vec2.size(); i++) { cout << iter2[i] << " "; } cout << endl; return 0;}
其中还有个问题我还没弄清楚,搞清楚后一定补上。
阅读全文
0 0
- vector第四步修炼之道
- vector第二步修炼之道
- vector第三步修炼之道
- vector第一步修炼之道
- 第四课--C++之vector
- CSS网站布局十步之第四步
- 七步入门CMake之第四步(自我检查)
- 第四步 Javaweb开发之HTTP协议
- 《程序员修炼之道:专业程序员必知的33个技巧》笔记-----第四章
- Spark修炼之道(高级篇)——Spark源码阅读:第四节 Stage划分
- 程序员修炼之道(通俗版)——第四章
- 程序员修炼之道
- 程序员修炼之道
- [原创]修炼之道
- 程序员修炼之道
- 程序员修炼之道
- 程序员修炼之道
- 程序员修炼之道
- Java压测之四两拨千斤
- java程序加载sigar库报异常的错误的解决
- 傻傻的情绪
- 在myeclipse中ssh框架搭建的麻烦问题
- C#中实现Form的Minimize、Maximize、Close按钮及任务栏图标
- vector第四步修炼之道
- 如何使用PowerBI将文件夹的内容中的所有文件合并为一张表进行统计
- 【在线等急急急!】相差为2的两个素数称为孪生素数。例如,3与5,41与43等都是孪生素数。设计程序求出指定区间上的所有孪生素数对。区间上限和下限由键盘获取。
- 手机号码验证--正则表达式
- Learning Spatial-Aware Regressions for Visual Tracking 阅读笔记
- [并查集]HAOI2006 旅行
- java编程思想--数组
- c extern用法
- CSS——!important的使用场景