最近忙得蛋疼,但还是想写点属于自己的东西。也不知道写点啥,最后决定试着自己实现STL中常用的几个集合,一来加深自己对STL的理解,二来看看自己是否有这个能力实现。实现目标就是:1能和STL兼容;2最大化的实现STL中的接口并保持一致。即将STL中的集合换成我写的也能用。这篇博客介绍的是vector的原理及实现。

先把vector的大致实现说一下,后面会给出完整的源码。

新增元素:Vector通过一个连续的数组存放元素,如果集合已满,在新增数据的时候,就要分配一块更大的内存,将原来的数据复制过来,释放之前的内存,在插入新增的元素。插入新的数据分在最后插入push_back和通过迭代器在任何位置插入,这里说一下通过迭代器插入,通过迭代器与第一个元素的距离知道要插入的位置,即int index=iter-begin()。这个元素后面的所有元素都向后移动一个位置,在空出来的位置上存入新增的元素。

        void insert(const_iterator iter,const T& t )
{
int index=iter-begin();
if (index<size_)
{
if (size_==capacity_)
{
int capa=calculateCapacity();
newCapacity(capa);
}
memmove(buf+index+,buf+index,(size_-index)*sizeof(T));
buf[index]=t;
size_++;
}
}

删除元素:删除和新增差不多,也分两种,删除最后一个元素pop_back和通过迭代器删除任意一个元素erase(iter)。通过迭代器删除还是先找到要删除元素的位置,即int index=iter-begin();这个位置后面的每个元素都想前移动一个元素的位置。同时我们知道erase不释放内存只初始化成默认值。

删除全部元素clear:只是循环调用了erase,所以删除全部元素的时候,不释放内存。内存是在析构函数中释放的。

        iterator erase(const_iterator iter)
{
int index=iter-begin();
if (index<size_ && size_>)
{
memmove(buf+index ,buf+index+,(size_-index)*sizeof(T));
buf[--size_]=T();
}
return iterator(iter);
}

迭代器iteraotr是STL的一个重要组成部分,通过iterator可以很方便的存储集合中的元素.STL为每个集合都写了一个迭代器, 迭代器其实是对一个指针的包装,实现一些常用的方法,如++,--,!=,==,*,->等, 通过这些方法可以找到当前元素或是别的元素. vector是STL集合中比较特殊的一个,因为vector中的每个元素都是连续的,所以在自己实现vector的时候可以用指针代替,如typedef T* iterator;typedef const T* const_iterator,如果STL中的函数能方便的操作自己写的集合,实现的迭代器最好继承std::iterator<std::forward_iterator_tag,T>。我实现vector的迭代器大概是这个样子:

template<typename T>

class viterator:public std::iterator<std::forward_iterator_tag,T>{}

后面会给出完整的代码,std::iterator<std::forward_iterator_tag,T>的源码如下:

template<class _Category,
class _Ty,
class _Diff = ptrdiff_t,
class _Pointer = _Ty *,
class _Reference = _Ty&>
struct iterator
{ // base type for all iterator classes
typedef _Category iterator_category;
typedef _Ty value_type;
typedef _Diff difference_type;
typedef _Diff distance_type; // retained
typedef _Pointer pointer;
typedef _Reference reference;
};

Iterator其中没有任何成员,只是定义了一组类型,所以继承它并不会让你的struct变大,这组类型是STL的内部契约,STL中的函数假设每个迭代器都定义了这些类型,所以只要你的迭代器定义了这些类型,就可以和STL函数集合一起使用。

我的vector实现源码如下:

#ifndef _CVECTOR_H_
#define _CVECTOR_H_ namespace cth
{
class NoCopy
{
public:
inline NoCopy(){}
NoCopy(const NoCopy&);
NoCopy& operator=(const NoCopy&);
}; template<typename T>
class viterator:public std::iterator<std::forward_iterator_tag,T>
{
public:
viterator()
{
t=NULL;
}
viterator(T* t_)
{
t=t_;
}
viterator(const viterator& other)
{
t=other.t;
}
viterator& operator=(const viterator& other)
{
t=other.t;
return *this;
} viterator& operator++()
{
t++;
return *this;
}
viterator operator++(int)
{
viterator iter=*this;
t++;
return iter;
}
viterator operator+(int count)
{
viterator iter=*this;
iter.t+=count;
return iter;
}
viterator& operator--()
{
t--;
return *this;
}
viterator operator--(int)
{
viterator iter=*this;
t--;
return iter;
}
viterator operator-(int count)
{
viterator iter=*this;
iter.t-=count;
return iter;
} int operator-(const viterator& other)
{
return t-other.t;
}
int operator-(const viterator& other)const
{
return t-other.t;
} T& operator*()
{
return *t;
}
const T& operator*() const
{
return *t;
} T* operator->()
{
return t;
}
const T* operator->() const
{
return t;
} inline bool operator!=(const viterator& other)
{
return t!=other.t;
}
inline bool operator!=(const viterator& other)const
{
return t!=other.t;
} inline bool operator==(const viterator& other)
{
return t==other.t;
}
inline bool operator==(const viterator& other)const
{
return t==other.t;
} inline bool operator<(const viterator& other)
{
return t<other.t;
}
inline bool operator<(const viterator& other)const
{
return t<other.t;
} inline bool operator<=(const viterator& other)
{
return t<=other.t;
}
inline bool operator<=(const viterator& other)const
{
return t<=other.t;
} inline bool operator>(const viterator& other)
{
return t>other.t;
}
inline bool operator>(const viterator& other)const
{
return t>other.t;
} inline bool operator>=(const viterator& other)
{
return t>=other.t;
}
inline bool operator>=(const viterator& other)const
{
return t>=other.t;
}
private:
T* t;
}; template<typename T>
class cvector:public NoCopy
{
public:
typedef viterator<T> iterator;//viterator<T>就是对一个指针的包装,所以完全可以用T*代替viterator <T>
typedef const viterator<T> const_iterator; //typedef T* iterator;
//typedef const T* const_iterator;
cvector()
{
initData();
}
cvector(int capa,const T& val=T())
{
initData(capa);
newCapacity(capacity_);
for (int i=;i<size_;i++)
buf[i]=val;
}
cvector(const_iterator first,const_iterator last)
{
initData(last-first);
newCapacity(capacity_);
iterator iter=iterator(first);
int index=;
while(iter!=last)
buf[index++]=*iter++;
} ~cvector()
{
if (buf)
{
delete[] buf;
buf=NULL;
}
size_=capacity_=;
}
void clear()
{
if (buf)
erase(begin(),end());
} void push_back(const T& t)
{
if (size_==capacity_)
{
int capa=calculateCapacity();
newCapacity(capa);
}
buf[size_++]=t;
}
void pop_back()
{
if (!empty())
erase(end() - );
} int insert(const_iterator iter,const T& t )
{
int index=iter-begin();
if (index<=size_)
{
if (size_==capacity_)
{
int capa=calculateCapacity();
newCapacity(capa);
}
memmove(buf+index+,buf+index,(size_-index)*sizeof(T));
buf[index]=t;
size_++;
}
return index;
}
iterator erase(const_iterator iter)
{
int index=iter-begin();
if (index<size_ && size_>)
{
memmove(buf+index ,buf+index+,(size_-index)*sizeof(T));
buf[--size_]=T();
}
return iterator(iter);
} iterator erase(const_iterator first,const_iterator last)
{
iterator first_=iterator(first);
iterator last_=iterator(last);
while(first_<=last_--)
erase(first_);
return iterator(first_);
} T& front()
{
assert(size_>);
return buf[];
}
T& back()
{
assert(size_>);
return buf[size_-];
}
T& at(int index)
{
assert(size_>);
return buf[index];
}
T& operator[](int index)
{
assert(size_> && index>= && index<size_);
return buf[index];
} bool empty() const
{
return size_==;
}
int size() const
{
return size_;
}
int capacity() const
{
return capacity_;
} iterator begin()
{
return iterator(&buf[]);
}
iterator end()
{
return iterator(&buf[size_]);
} private:
void newCapacity(int capa)
{
capacity_=capa;
T* newBuf=new T[capacity_];
if (buf)
{
memcpy(newBuf,buf,size_*sizeof(T));
delete [] buf;
}
buf=newBuf;
} inline int calculateCapacity()
{
return capacity_*/+ ;
} inline void initData(int capa)
{
buf=NULL;
size_=capacity_=capa>?capa:;
}
int size_;
int capacity_ ;
T* buf;
}; struct Point
{
Point(int x_=,int y_=):x(x_),y(y_){}
int x,y;
}; bool operator<(const Point& p1,const Point& p2)
{
if(p1.x<p2.x)
{
return true;
}else if(p1.x>p2.x)
{
return false;
}
return p1.y<p2.y;
} void cvectorTest()
{
cvector<Point> vect;
for (int i=;i<;i++)
{
Point p(i,i);
vect.push_back(p);
} cvector<Point>::iterator iter=vect.begin();
while (iter!=vect.end())
{
cout<< "[" << iter->x << " " << iter->y <<"], ";
++iter;
}
iter=vect.begin()+;
vect.insert(iter,Point(,));
iter=vect.end()-;
vect.insert(iter,Point(,));
cout<<endl<<endl<<"插入两个元素后:"<<endl;
iter=vect.begin();
while (iter!=vect.end())
{
cout<< "[" << iter->x << " " << iter->y <<"], ";
++iter;
}
std::sort(vect.begin(),vect.end());
cout<<endl<<endl<<"排序后:"<<endl;
iter=vect.begin();
while (iter!=vect.end())
{
cout<< "[" << iter->x << " " << iter->y <<"], ";
++iter;
}
vect.erase(vect.begin()+);
vect.erase(vect.begin()+);
cout<<endl<<endl<<"删除之前新增的两个元素"<<endl;
iter=vect.begin();
while (iter!=vect.end())
{
cout<< "[" << iter->x << " " << iter->y <<"], ";
++iter;
}
vect.clear();
cout<<endl<<endl<<"执行clear之后"<<endl;
cout<<"size="<<vect.size()<<",capacity="<<vect.capacity(); cvector<Point> vect1;
for (int i=;i<;i++)
{
Point p(i,i);
vect1.push_back(p);
}
cout<<endl<<endl<<"从别的cvector复制数据:"<<endl; cvector<Point> vect2(vect1.begin(),vect1.end());
vect2.pop_back();
vect2.pop_back();
for(int i=;i<vect2.size();i++)
{
cout<<"["<<vect2[i].x<<","<<vect2[i].y<<"], ";
} cout<<endl;
} } #endif

实例代码级运行结果如下:

    struct Point
{
Point(int x_=,int y_=):x(x_),y(y_){}
int x,y;
}; bool operator<(const Point& p1,const Point& p2)
{
if(p1.x<p2.x)
{
return true;
}else if(p1.x>p2.x)
{
return false;
}
return p1.y<p2.y;
} void cvectorTest()
{
cvector<Point> vect;
for (int i=;i<;i++)
{
Point p(i,i);
vect.push_back(p);
} cvector<Point>::iterator iter=vect.begin();
while (iter!=vect.end())
{
cout<< "[" << iter->x << " " << iter->y <<"], ";
++iter;
}
iter=vect.begin()+;
vect.insert(iter,Point(,));
iter=vect.end()-;
vect.insert(iter,Point(,));
cout<<endl<<endl<<"插入两个元素后:"<<endl;
iter=vect.begin();
while (iter!=vect.end())
{
cout<< "[" << iter->x << " " << iter->y <<"], ";
++iter;
}
std::sort(vect.begin(),vect.end());
cout<<endl<<endl<<"排序后:"<<endl;
iter=vect.begin();
while (iter!=vect.end())
{
cout<< "[" << iter->x << " " << iter->y <<"], ";
++iter;
}
vect.erase(vect.begin()+);
vect.erase(vect.begin()+);
cout<<endl<<endl<<"删除之前新增的两个元素"<<endl;
iter=vect.begin();
while (iter!=vect.end())
{
cout<< "[" << iter->x << " " << iter->y <<"], ";
++iter;
}
vect.clear();
cout<<endl<<endl<<"执行clear之后"<<endl;
cout<<"size="<<vect.size()<<",capacity="<<vect.capacity(); cvector<Point> vect1;
for (int i=;i<;i++)
{
Point p(i,i);
vect1.push_back(p);
}
cout<<endl<<endl<<"从别的cvector复制数据:"<<endl; cvector<Point> vect2(vect1.begin(),vect1.end());
vect2.pop_back();
vect2.pop_back();
for(int i=;i<vect2.size();i++)
{
cout<<"["<<vect2[i].x<<","<<vect2[i].y<<"], ";
} cout<<endl;
}

之后还会有list,set,map等的实现,敬请期待......

《STL系列》之vector原理及实现的更多相关文章

  1. 《STL系列》之map原理及实现

    上一篇文章<STL系列>之vector原理及实现,介绍了vector的原理及实现,这篇文章介绍map的原理及实现.STL实现源码下载.STL中map的实现是基于RBTree的,我在实现的时 ...

  2. Java 集合系列 05 Vector详细介绍(源码解析)和使用示例

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  3. [知识点]C++中STL容器之vector

    零.STL目录 1.容器之map 2.容器之vector 3.容器之set 一.前言 关于STL和STL容器的概念参见STL系列第一篇——map(见上).今天介绍第二个成员——vector. 二.用途 ...

  4. [STL] STL各容器实现原理

    STL共有六大组件1.容器 2.算法 3.迭代器 4.仿函数 6.适配器 STL容器的实现原理 STL来管理数据十分方便,省去了我们自己构建数据结构的时间.其实,STL的实现也是基于我们常见的数据结构 ...

  5. java基础解析系列(七)---ThreadLocal原理分析

    java基础解析系列(七)---ThreadLocal原理分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)-- ...

  6. 转:用STL中的vector动态开辟二维数组

    用STL中的vector动态开辟二维数组 源代码:#include <iostream>#include <vector>using namespace std;int mai ...

  7. java基础解析系列(六)---注解原理及使用

    java基础解析系列(六)---注解原理及使用 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)---Integer缓存及 ...

  8. STL中的Vector相关用法

    STL中的Vector相关用法 标准库vector类型使用需要的头文件:#include <vector>. vector 是一个类模板,不是一种数据类型,vector<int> ...

  9. (转)C++ STL中的vector的内存分配与释放

    C++ STL中的vector的内存分配与释放http://www.cnblogs.com/biyeymyhjob/archive/2012/09/12/2674004.html 1.vector的内 ...

  10. C++STL中的vector的简单实用

    [原创] 使用C++STL中的vector, #include <stdio.h> #include<stdlib.h> #include<vector> usin ...

随机推荐

  1. [php-src]理解Php内核中的函数与INI

    内容均以php-5.6.14为例. 一. 函数结构 内核中定义一个php函数使用 PHP_FUNCTION 宏 包装,扩展也不例外,该宏在 ./main/php.h:343 有着一系列类似以 PHP ...

  2. 互联网云生态下DDOS安全产品的一些考虑和测试方法(一)

    DDOS攻击简介 安全的三要素——“保密性”.“完整性”和“可用性”中,DOS(Denial of Service拒绝服务攻击)所针对的目标是服务的“可用性”.这种攻击方式利用目标系统的网络服务功能缺 ...

  3. 【转】Mysql 存储引擎中InnoDB与Myisam的主要区别

    1, 事务处理 innodb 支持事务功能,myisam 不支持. Myisam 的执行速度更快,性能更好.   2,select ,update ,insert ,delete 操作   MyISA ...

  4. 关于MATHAPP的测试

    这是我个人的单元测试博客仅供参考,想了解更全面的信息可请见我们团队的博客http://www.cnblogs.com/xjy-gg/p/5422868.html 首先,从世界那里下载adt-bundl ...

  5. win7连接共享打印机 错误为

    1.  xp局域网共享打印机,本机运行 –>  \\共享电脑ip –> 选择驱动目录 .INF 文件 –> 确认. 直接报错..... 2.  参考方法: 开始——设备和打印机——添 ...

  6. java对xml文件做增删改查------摘录

    java对xml文件做增删改查 package com.wss; import java.io.File;import java.util.ArrayList;import java.util.Lis ...

  7. sql关键字的解释执行顺序

      sql关键字的解释执行顺序 分类: 笔试面试总结2013-03-17 14:49 1622人阅读 评论(1) 收藏 举报 SQL关键字顺序 表里面的字段名什么符号都不加,值的话一律加上单引号 有一 ...

  8. 注册表(regedit)

    注册表(Registry,繁体中文版Windows称之为登录档)是Microsoft Windows中的一个重要的数据库,用于存储系统和应用程序的设置信息. 打开方式:1.开始>>运行.中 ...

  9. jenkins2 Jenkinsfile

    推荐使用Jenkinsfile代替将groovy脚本直接写在jenkins job里. 文章来自:http://www.ciandcd.com文中的代码来自可以从github下载: https://g ...

  10. JS字符串

    字符串 双引号""或单引号''包围的都是字符串. 创建字符串 直接用单引号或双引号包围. var str1="我的过去"; console.log(typeof ...