Vector的一种实现(二)
增加了逆置迭代器的实现
以及swap功能
完整代码如下:
#ifndef VECTOR_H_
#define VECTOR_H_ #include <stddef.h>
#include <algorithm>
#include <memory> template <typename T>
class Vector
{
public:
typedef T *iterator;
typedef const T *const_iterator;
typedef size_t size_type;
typedef T value_type; //逆置迭代器
class reverse_iterator
{
public:
reverse_iterator(iterator it = NULL) :current_(it) { }
iterator base() const { return current_; } reverse_iterator &operator++()
{
--current_;
return *this;
}
reverse_iterator operator++(int)
{
reverse_iterator temp(*this);
--current_;
return temp;
}
reverse_iterator &operator--()
{
++current_;
return *this;
}
reverse_iterator operator--(int)
{
reverse_iterator temp(*this);
++current_;
return temp;
} T &operator*()
{
iterator temp = current_;
return *--temp;
} T *operator->()
{
iterator temp = current_;
return --temp;
} friend bool operator==(const reverse_iterator &lhs, const reverse_iterator &rhs)
{
return lhs.current_ == rhs.current_;
} friend bool operator!=(const reverse_iterator &lhs, const reverse_iterator &rhs)
{
return lhs.current_ != rhs.current_;
} private:
iterator current_;
}; //const逆置迭代器
class const_reverse_iterator
{
public:
const_reverse_iterator(const_iterator it = NULL) :current_(it) { }
const_iterator base() const { return current_; } const_reverse_iterator &operator++()
{
--current_;
return *this;
}
const_reverse_iterator operator++(int)
{
const_iterator temp(*this);
--current_;
return temp;
}
const_reverse_iterator &operator--()
{
++current_;
return *this;
}
const_reverse_iterator operator--(int)
{
const_iterator temp(*this);
++current_;
return temp;
} const T &operator*() const
{
const_iterator temp = current_;
return *(--temp);
} const T *operator->() const
{
const_iterator temp = current_;
return --temp;
} friend bool operator==(const const_reverse_iterator &lhs, const const_reverse_iterator &rhs)
{
return lhs.current_ == rhs.current_;
} friend bool operator!=(const const_reverse_iterator &lhs, const const_reverse_iterator &rhs)
{
return lhs.current_ != rhs.current_;
} private:
const_iterator current_;
}; Vector() { create(); }
explicit Vector(size_type n, const T &t = T()) { create(n, t); }
Vector(const Vector &v) { create(v.begin(), v.end()); }
~Vector() { uncreate(); } Vector &operator=(const Vector &other);
T &operator[] (size_type i) { return data_[i]; }
const T &operator[] (size_type i) const { return data_[i]; } void push_back(const T &t);
void swap(Vector &rhs)
{
std::swap(data_, rhs.data_);
std::swap(avail_, rhs.avail_);
std::swap(limit_, rhs.limit_);
} size_type size() const { return avail_ - data_; }
size_type capacity() const { return limit_ - data_; } iterator begin() { return data_; }
const_iterator begin() const { return data_; }
iterator end() { return avail_; }
const_iterator end() const { return avail_; } reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } private:
iterator data_; //首元素
iterator avail_; //末尾元素的下一个位置
iterator limit_; //内存的后面一个位置 std::allocator<T> alloc_; //内存分配器 void create();
void create(size_type, const T &);
void create(const_iterator, const_iterator); void uncreate(); void grow();
void uncheckedAppend(const T &);
}; template <typename T>
Vector<T> &Vector<T>::operator=(const Vector &rhs)
{
if(this != &rhs)
{
uncreate(); //释放原来的内存
create(rhs.begin(), rhs.end());
} return *this;
} template <typename T>
void Vector<T>::push_back(const T &t)
{
if(avail_ == limit_)
{
grow();
}
uncheckedAppend(t);
} template <typename T>
void Vector<T>::create()
{
//分配空的数组
data_ = avail_ = limit_ = 0;
} template <typename T>
void Vector<T>::create(size_type n, const T &val)
{
//分配原始内存
data_ = alloc_.allocate(n);
limit_ = avail_ = data_ + n;
//向原始内存填充元素
std::uninitialized_fill(data_, limit_, val);
} template <typename T>
void Vector<T>::create(const_iterator i, const_iterator j)
{
data_ = alloc_.allocate(j-i);
limit_ = avail_ = std::uninitialized_copy(i, j, data_);
} template <typename T>
void Vector<T>::uncreate()
{
if(data_)
{
//逐个进行析构
iterator it = avail_;
while(it != data_)
{
alloc_.destroy(--it);
} //真正的释放内存
alloc_.deallocate(data_, limit_ - data_);
}
//重置指针
data_ = limit_ = avail_ = 0;
} template <typename T>
void Vector<T>::grow()
{
//内存变为两倍
size_type new_size = std::max(2 * (limit_ - data_), std::ptrdiff_t(1));
//分配原始内存
iterator new_data = alloc_.allocate(new_size);
//复制元素
iterator new_avail = std::uninitialized_copy(data_, avail_, new_data); uncreate(); //释放以前的内存,以及析构元素 data_ = new_data;
avail_ = new_avail;
limit_ = data_ + new_size;
} template <typename T>
void Vector<T>::uncheckedAppend(const T &val)
{
alloc_.construct(avail_++, val);
} #endif /* VECTOR_H_ */
测试代码如下:
#include "Vector.hpp"
#include <iostream>
#include <string>
using namespace std; //测试const reverse迭代器
void print(const Vector<string> &vec)
{
for(Vector<string>::const_reverse_iterator it = vec.rbegin();
it != vec.rend();
++it)
{
cout << *it << " ";
}
cout << endl;
} int main(int argc, char const *argv[])
{
Vector<string> vec(3, "hello"); for(Vector<string>::const_iterator it = vec.begin();
it != vec.end();
++it)
{
cout << *it << " ";
}
cout << endl; cout << "size = " << vec.size() << endl;
cout << "capacity = " << vec.capacity() << endl;
vec.push_back("foo");
vec.push_back("bar"); cout << "size = " << vec.size() << endl;
cout << "capacity = " << vec.capacity() << endl; for(Vector<string>::reverse_iterator it = vec.rbegin();
it != vec.rend();
++it)
{
cout << *it << " ";
}
cout << endl; print(vec); Vector<string> vec2;
vec2.push_back("beijing");
vec2.push_back("shanghai");
vec2.push_back("guangzhou");
print(vec2); vec.swap(vec2);
print(vec);
print(vec2); return 0;
}
Vector的一种实现(二)的更多相关文章
- c++中vector向量几种情况的总结(向量指针,指针的向量)
1.标准库vector类型 vector 是同一种类型的对象的集合.每一个对象都有一个相应的整数索引值.标准库将负责管理与存储元素相关的内存.我们把 vector 称为容器,是由于它能够包括其它对象. ...
- 论C++11 中vector的N种遍历方法
随着C++11标准的出现,C++标准添加了许多有用的特性,C++代码的写法也有比较多的变化. vector是经常要使用到的std组件,对于vector的遍历,本文罗列了若干种写法. (注:本文中代码为 ...
- Java的23种设计模式 <二>
1.单例模式(Singleton Pattern) 定义:Ensure a class has only one instance, and provide a global point of acc ...
- 7、二种 为二个不同的子网配置DHCP服务器(中继代理服务器)
环境如下: (参考之前,保证二个子网可以互相ping通) 虚拟机vm1 192.168.170.3 VMnet8 (NAT模式) 虚拟 ...
- 用vector构造自动扩容的二维数组
#include <iostream> #include <string> #include <vector> using namespace std; int m ...
- vector的几种初始化和遍历
随着C++11标准的出现,vector出现了新的初始化和遍历用法,但是vs2010和较高版本并没有能完全支持C++11标准,所以我就将它的所有的用法归纳了一下. vector的初始化 vector基本 ...
- 一种局部二值化算法:Sauvola算法
之前接触过全局二值化(OTSU算法),还有OPENCV提供的自适应二值化,最近又了解到一种新的局部二值化算法,Sauvola算法. 转载自:http://www.dididongdong.com/ar ...
- C++11中vector的几种遍历方法
假设有这样的一个vector: vector<int> line={1,2,3,4,5,6,7,8,9}; 需要输出vector里的每个元素,主函数如下: void showvec(con ...
- C语言:指针的几种形式二
一.const指针 1.const int* p和int const* p:两者意义是相同的.指向的内容是只读数据,不可以q改变:但是指向的地址可以改变. 2.int* const p:必须先对指针初 ...
随机推荐
- C#操作windows事件日志项
/// <summary> /// 指定事件日志项的事件类型 /// </summary> public enum EventLogLevel { /// <summar ...
- [ CodeVS冲杯之路 ] P1017
不充钱,你怎么AC? 题目:http://codevs.cn/problem/1017/ 看到题目最下面有一个喜人的提示 那这就意味着我们不用写高精度了是不是,直接开 long long 存 设 f[ ...
- cygwin设置
解决乱码问题 # 设置为中文环境,使提示成为中文 export LANG =" zh_CN.UTF-8 " # 输出为中文编码 export OUTPUT_CHARSET =& ...
- (十)stm32 GPIO口复用,重映射 RCC_APB2Periph_AFIO
什么时候需要用到RCC_APB2Periph_AFIO--复用IO时钟的使用 需要用到外设的重映射功能时才需要使能AFIO的时钟 外部中断(EXTI)中与AFIO有关的寄存器是AFIO-EXTICR1 ...
- 如何使用python下载网站上的视频
youtube-dl 从名字上也能看出来,是专门用来下载YouTube的视频. 不过本人对YouTube不感兴趣,但是这个模块可以用来下载bilibili上的视频我们就来试一试 首先pip insta ...
- Starting MySQL... ERROR! The server quit without updating PID file 问题解决
今天遇到一个mysql起不来,不知为啥挂了,启动是下面的报错 Starting MySQL... ERROR! The server quit without updating PID file 后来 ...
- 天猫首页迷思之-jquery实现整个div的懒加载(1)
懒加载是众所周知的减少网页负载,提高性能的方法,不少大型用图片用的多的网站都用到了. 于是我网上一搜,得到一插件:jquery.lazyload 网址:http://www.appelsiini ...
- 利用NPOI组件产Excel完整操作
最终还是要使用NPOi了.刚开始做的是用com组件,发现如果本机不按照excel就不能使用,后来把其中一支改为了用Itextsharp产生pdf,但是还有几支批次要产生Excel,只能改用NPOI了. ...
- (1)安装Xamarin
()一.安装 1.安装xamarin 2.下载jdk8 https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads- ...
- axure8.1.0.3377授权码
被授权人:zdfans.com 授权密钥:gP5uuK2gH+iIVO3YFZwoKyxAdHpXRGNnZWN8Obntqv7++FF3pAz7dTu8B61ySxli