vector实现了动态数组,用于元素数量变化的对象数组。像数组一样,vector类也用从0开始的下标表示元素的位置;但和数组不同的是,当vector对象创建后,数组的元素个数会随着vector对象元素个数的增大和缩小而自动变化。c++ STL中容器中的一个。是封装好的数据结构和算法(类模板),保存在容器的数据都很安全。
那怎么制作简单的vector呢?下面分几步进行介绍
1.数组:
数组用来存数据,数组的本质就是连续的内存段。首地址就是数组名。
2.动态数组:
动态数组的一般使用:
int *p=new int[5];
for(int i=0;i<5;i++){p[i]=i;}
动态数组内存的使用上是动态的,什么时候想删掉都可以释放
delete[]p;
而数组只能在程序运行完才能释放。
动态数组同时可以实现内存的动态占用。就是插入一个int类型的数据,则申请4个字节(不同电脑int类型占用字节数可能不同,这里不做论述),插入2个,则申请8个字节以此类推,不会造成内存的浪费。
那么如何实现这种效果呢?
一般分5步
1.新开内存 2.把原内存段中的数据拷贝到新开的内存中 3.原内存释放 4.p指向新的内存段 5.数据段存入
int *p=NULL;
int size=0; //当前数据个数
void push(int data)//传入数据
{int *pnew=new int[size+1];
if(p)
{
memcpy(pnew,p,size*sizeof(int));}//把一个内存段(第二个参数)中的数据拷贝到另一个内存段(第一个)中
delete[p];}
p=pnew;
p[size]=data;
size++;
}
3.动态数组类:
上面已经实现数组内存的动态使用,但上面的方法非常不安全,因为你只需要在主函数改变p所指的内存的值则值就改变了,所以我们需要把这个函数封装到类里面去就安全了。
class dongtai{
int *p;
int size;
public:
dongtai();
void push(int data);
};
dongtai::dongtai()//初始化
{p=NULL;size=0;}
void dongtai::push(int data)
{
.....//和上面的代码基本一样
}
这时就不可以通过用p[]的方式改变数据,必须通过函数才能加入数据,这样就很安全了。但是这个还没有完,因为这个还不够优化,假如有几万的数据要加入,我们要存放几万的数据,需要开辟几万次内存。像上述的方式,加入一个数据就开辟一次内存,的确不会造成内存的浪费,但是开辟内存是消耗cpu的速度 。所以前辈们想到一个方法就是每次开辟内存,开辟之前内存段的1.5倍的内存。例如需要加入99个数据只需要开辟13次,开辟了141*4内存,虽然浪费了一些,但是节约了时间,这种用空间换时间还是很划得来。所以代码需要这样改
int *p=NULL;
int size=0; //当前数据个数
int maxsize=0;//容量
void push(int data)//传入数据
{
int *pnew=NULL;
if(maxsize<=size)//需要开内存
{
maxsize=maxsize+(maxsize/2>1?(maxsize/2):1);//排除maxsize=0没法变成1.5倍的可能
pnew=new int[maxsize];
if(p)
{
memcpy(pnew,p,size*sizeof(int));
delete[p];}
p=pnew;
}
p[size]=data;
size++;
}
然后在放入类里面重新封装就行了
4动态数组模板类:
完成上面基本已经完成vector的加入数据的制作,但是还差一个问题就是上面都是加入整形的数据,如果有加入浮点型或者其他类型,那么还要重新在写,那么就很麻烦。所以我们要把它变成模板类。如何设置成模板类呢?需要我们在类里面操作
#pragma once
template<class T> //类模板,将所有数据包括子函数的类型包括都换成T
class dongtai{
T *p;
int size;
public:
dongtai();
void push(T data);
};
template<class T>
dongtai::dongtai()//初始化
{p=NULL;size=0;}
template<class T>
void dongtai::push(T data)
{
.....//和上面的代码基本一样
}
这样我们就已经完成类vector的一个功能。写了这些只是为了理解vector的一些工作原理,事实上有现成的,平时我们直接#include就可以使用。