STL源码初步接触

STL = Standard Template Library,直译过来是:标准模板库,是惠普实验室开发的一系列软件的统称。从根本上说,STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其他一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。STL的目的是标准化组件,这样就不用重新开发,可以使用现成的组件。STL现在是C++的一部分,因此不用额外安装什么。STL所实现的,是依据泛型思维架设起来的一个概念结构。说了这么多还是不知道STL是个什么东东,今天只是初接触这个概念,感觉很高深的样子,先这样理解吧,STL就是一个仓库,一个存放各种工具的仓库。它的工具分为六大类(六大组件) :

容器(containers):各种数据结构,如Vector,list,deque,set,map,用来存放底层数据。一般有序列式(下面要写的Vector就是个这种)、关联式等。

算法(algorithms):各种常用算法如:sort,search,copy,erase……

迭代器(iterator):扮演容器与算法之间的胶合剂,是所谓的“泛型指针”,共5种类型,以及他们的衍生变化。所有的STL容器都附带有自己专属的迭代器。原生指针也是一种迭代器。

仿函数(functor):行为类似函数可作为算法的某种策略。一般函数指针可认为是侠义的仿函数。

配接器(adapter):一种用来修饰容器,或仿函数,或迭代器接口的东西。

配置器(allocators)负责空间配置与管理。配置器是一个实现了动态空间配置、空间管理、空间释放的class template。

因为下面主要是实现Vector的简单操作,所以就再多讲一点它。Vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。因此Vector的运用对于内存的合理运用与运用得灵活性有很大的帮助。Vector维护的是一个连续的空间,无论元素的型别为何,普通指针都可以作为Vector的迭代器而满足所有必要条件。

Vector 的简单实现:

   #pragma once
#include<iostream>
#include<assert.h>
#include<stdlib.h>
using namespace std;
template<class T>
class Vector
{
public:
typedef T* Iterator;
typedef const T* Citerator;
public:
Vector()
:start(NULL)
,finish(NULL)
,endofstorage(NULL)
{}
Vector(const Vector<T>& v)
//:start(new T[v.endofstorage - v.start])
//, finish(v.finish )
//, endofstorage(v.endofstorage)
:start(new T[v.endofstorage - v.start])
, finish(start + (v.finish - v.start))
,endofstorage(start + (v.endofstorage - v.start)) {
my_memcopy(start, v.start, sizeof(T)*(v.endofstorage - v.start));
}
//向Vector中存入size个元素
Vector(Citerator array, size_t size)
:start(new T[size])
, finish(start)
, endofstorage(start + size) {
for (size_t index = ; index < size; ++size) {
start[index] = array[index];
finish++;
}
}
Vector<T>&operator=(const Vector<T>& v) {
if (this != &v) {
Vector<int>tmp(v);
swap(tmp);
}
return *this;
}
~Vector(){
if (start) {
delete[] start;
start = NULL;
// delete[] finish;
finish = NULL;
// delete[] endofstorage;
endofstorage = NULL;
}
}
// 返回首元素的迭代器
Iterator Begin() {
return start;
}
Citerator Begin()const {
return start;
}
// 获取Vector中最后一个元素的下一个位置
Iterator End() {
return finish:
}
Iterator End()const {
return finish;
}
size_t Size()const {
return finish - start;
}
size_t Capacity()const {
return endofstorage - start;
}
bool Empty()const {
return finish == start;
}
T& operator[](size_t index) {
return start[index];
}
const T& operator[](size_t index)const {
return start[index];
}
T& At(size_t index) {
if ((index <= Size()) && (index >= ))
return start[index];
}
const T& At(size_t index)const {
if ((index <= Size()) && (index >= ))
return start[index];
}
// 获取Vector中的第一个元素
T& Front() {
return srart[];
}
const T& Front()const {
return start[];
}
// 获取Vector中的最后一个元素
T& Back() {
return start[finish - start];
}
const T& Back()const {
return start[finish - start];
}
void PushBack(const T& x) {
capacity();
// start[finish - start + 1] = x;
start[finish - start] = x;
finish++;
}
void PopBack() {
if (!Empty()) {
finish--;
}
}
// 在pos位置上插入元素x
Iterator Insert(Iterator pos, const T& x) {
for (size_t index = Size(); index >= (size_t)(pos - start); index--) {
start[index + ] = start[index];
}
*pos = x;
finish++;
return pos;
}
// 删除pos位置上面的元素
Iterator Erase(Iterator pos) {
for (size_t index = (size_t)(pos - start); index < Size(); index++) {
start[index] = start[index + ];
}
finish--;
return pos;
}
// 给Vector赋值n个值为x的元素
void Assign(size_t n, const T& x) {
if (n > endofstorage - start) {
finish = start + n;
capacity();
for (size_t index = ; index < n; index++) {
start[index] = x;
}
}
else {
for (size_t index = ; index < n; index++)
start[index] = x;
}
finish = start + n;
}
public:
//自己管理 扩容
void capacity() {
if (finish >= endofstorage) {
size_t capacity = * (endofstorage - start) + ;
Iterator tmp = new T[capacity];
// 拷贝元素
my_memcopy(tmp, start, sizeof(T)*(endofstorage - start));
size_t ret = finish-start;
delete start;
start = tmp;
finish = start + ret;
endofstorage = start + capacity;
//
/*Iterator pos = start;
size_t index = 0;
while (pos < endofstprage)
temp[index++] = *pos++;
deleta[] start;
start = temp;
finish = start + index;
endofstorage = start + capacity;*/ }
}
void swap(Vector<T>& v) {
std::swap(start, v.start);
std::swap(finish, v.finish);
std::swap(endofstorage, v.endofstorage);
}
void Print() {
for (size_t i = ; i < Size(); i++)
{
cout << start[i] << " ";
}
cout << endl;
}
void* my_memcopy(void* dest, const void* src, size_t sz) {
//assert(!dest || !src);
assert(dest != NULL || src != NULL);
char* ret = (char*)dest;
char* tmp = (char*)src;
while (sz--) {
*ret = *tmp;
ret++;
tmp++;
}
return dest;
}
private:
Iterator start;
Iterator finish;
Iterator endofstorage;
};

其中,注释掉的代码部分是我曾经踩过的坑,下面是部分测试代码

 #include"vector.h"
void Test1()
{
Vector<int> list1;
list1.PushBack();
list1.PushBack();
list1.PushBack();
list1.PushBack();
list1.PushBack();
list1.Print();
Vector<int> list2;
list2.PushBack();
list2.PushBack();
list2.PushBack();
list2.PushBack();
list2.PushBack();
list2.Print();
list1 = list2;
list1.Print();
}
void Test2()
{
Vector<int> list1;
list1.PushBack();
list1.PushBack();
list1.PushBack();
list1.PushBack();
list1.PushBack();
list1.Print();
list1.PopBack();
list1.Print();
list1.Insert(&list1.At(), );
list1.Print();
list1.Erase(&list1.At());
list1.Print();
}
int main()
{
Test1();
Test2();
getchar();
return ;
}

注意:扩容时函数中my_memcpy()函数,它的本质就是值拷贝,当Vector中存放的内置类型时没有任何问题,但是像String类这种问题就无法解决。所以下面给出了另一种写法。

 /*Iterator pos = start;
size_t index = 0;
while (pos < endofstprage)
temp[index++] = *pos++;
deleta[] start;
start = temp;
finish = start + index;
endofstorage = start + capacity;*/

C++模板--实现容器适配器的更多相关文章

  1. 8、泛型程序设计与c++标准模板库2.5容器适配器

    容器适配器是用来扩展7中基本容器的,是修改和调整其他类接口的类.他们不提供存放数据的实际数据结构的实现方法,而且容器适配器也不支持迭代器. 1.标准栈容器 使用STL中的标准栈为程序员提供了一层附加的 ...

  2. C++顺序性容器、关联性容器与容器适配器

    什么是容器 首先,我们必须理解一下什么是容器,在C++ 中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对像的指针,这种对象类型就叫做容器.很简单,容器就是保存其它对象的对象 ...

  3. C++ 容器:顺序性容器、关联式容器和容器适配器

    什么是容器 首先,我们必须理解一下什么是容器,在C++ 中容器被定义为:在数据存储上,有一种对象类型,它可以持有其它对象或指向其它对像的指针,这种对象类型就叫做容器.很简单,容器就是保存其它对象的对象 ...

  4. 初步STL该容器适配器

    容器适配器 特点 容器一定的顺序来实现(让现有的以集装箱堆放/式工作) 分类 1) stack: 头文件 <stack> • 栈 -- 后进先出 2) queue: 头文件 <que ...

  5. 容器适配器————queue

    只能访问 queue<T> 容器适配器的第一个和最后一个元素.只能在容器的末尾添加新元素,只能从头部移除元素. 操作 queue<int> q;//创建一个int型的空队列q ...

  6. C++ Primer : 第九章 : vector变长、string的其他操作以及容器适配器

    vector变长机制.string的其他构造方法,添加.替换和搜索操作,string比较和数值转换,最后是容器适配器. vector对象是如何增长的 vector和string类型提供了一些成员函数, ...

  7. c++ 顺序容器学习 - 容器适配器

    摘要: 对 容器适配器 的疑问. 刚开始接触 容器适配器 时,总感觉怪怪的,认为多此一举,顺手搜了搜,原来我在这一点is not alone: STL容器适配器的用途 其中有个老兄说的好,这里 引用一 ...

  8. C++ Primer 学习笔记_33_STL实践与分析(7) --容器适配器

    STL实践与分析 --容器适配器 引: 除了顺序容器.标准库还提供了三种顺序容器适配器:queue,priority_queue和stack.适配器是标准库中的概念.包含容器适配器,迭代器适配器和函数 ...

  9. STL之容器适配器queue的实现框架

    说明:本文仅供学习交流,转载请标明出处,欢迎转载! 上篇文章STL之容器适配器stack的实现框架已经介绍了STL是怎样借助基础容器实现一种经常使用的数据结构stack (栈),本文介绍下第二种STL ...

随机推荐

  1. 项目架构开发:数据访问层之Query

    接上文 项目架构开发:数据访问层之Repository 上一章我们讲了IRepository接口,这张我们来讲IQuery 根据字面意思就可以知道,这次主要讲数据查询,上一章我们只针对单表做了查询的操 ...

  2. “使用多target来构建大量相似App”,唐巧大神理论验证(附工程代码地址)

    无意间看到巧神的文章时,感觉非常兴奋,此文章正好解决了公司目前项目的痛点. 读到以下关键一段时,不甚明了,故自己做了实验分享给有缘人. "我们的每个课程的资源文件都具有相同的文件名,例如首页 ...

  3. Windows 黑屏问题

    这两天使用Microsoft Visual Studio编译项目,不断黑屏闪现!回想下应该是之前设置的DOS窗口全屏的原因. 记得又一次使用MSDOS,老感觉屏幕台下,于是就设置成了全屏显示,全屏后发 ...

  4. Oracle Jdbc驱动下载及安装本地maven仓库

    由于二进制许可 binary license的限制,oracle jdbc驱动不能通过共有仓库来获取,所以你可以下载下来添加到自己的本地仓库或私有仓库中. 添加到本地仓库步骤如下: 下载Oracle ...

  5. 事件日志:无法加载站点/服务的所有 ISAPI 筛选器。因此启动中止。

    事件日志:无法加载站点/服务的所有 ISAPI 筛选器.因此启动中止. Service Unavailable解决 故障状态:Internet 信息服务(IIS)管理器 里 应用程序池出现错误 “应用 ...

  6. 通过udev创建ASM共享磁盘(RAC)

    OS:RedHat EL6.0 Oracle:   Oracle 11gR2 在Oracle 11gR2,构建RAC时可以通过ASM创建asm disk,但是需要安装asmlib相关软件:对于RedH ...

  7. 移动端利用rem实现自适应布局

    好久没有写博客了,刚好说说最近遇到的移动端布局问题吧. 本来一直是觉得我的页面布局能力还是不错的,当然,是相对于较基础的来说还是不错的.不过,自己写的案例终归是跟实际开发有区别的,自己写案例的是觉得这 ...

  8. PDCA循环原理

    1.PDCA循环原理:plan  do  check action 以pdca质量环模型为质量控制和保证的理论依据,对软件质量进行把控. plan计划阶段:项目质量规划 1.分析现状,找出质量问题 2 ...

  9. SQL AlawaysOn 之五:ISCSI共享磁盘

    用于存放SQL数据库 1.安装服务 2.安装完成后要求重启计算机.添加该功能要配置计算机,如果是正式服务器,那种不能关机太久的服务器,请慎用. 重启之后看到文件和储存服务,击击进去 3.看到ISCSI ...

  10. MySQL表-----查询------

    ``模糊查询4.2.1[使用like进行模糊查询]注意:like运算副只用于字符串,所以仅与char和varchar数据类型联合使用例:select * from a where name like ...