1.定义一个容器。
【】的运算符重载函数。
产生一个以系统时间为种子的随机数
srand(time(0));
vector向量容器?
用一个指针直接指向一个节点。
需要一种通用的方式来遍历任何容器,链表容器
以下标方式遍历容器?向量容器
数组
链表
二维数组
哈希表
红黑树
提供下标运算符重载函数。
通用?有一个迭代器,通用
每个容器底层的数据结构不同
迭代器和容器时一一对应的。
把迭代器这个类,设计成容器的嵌套类型,就是给当前容器提供遍历。
嵌套类型,不能直接访问。带上作用域。
访问当前容器的迭代器。
给容器提供
迭代器类型。
把容器第0号位置元素的迭代器返回回去。‘’
iteration end();把容器末尾元素的后继位置的迭代器返回
必须给迭代器提供!=运算符重载函数。
oop最大的特点:封装
容器底层的数据结构。
提倡同一前置++(自定义)
对象的前置++不产生临时对象,直接操作本身。
迭代器,迭代某个位置的元素。
容器的迭代器都是提供好的。
迭代器的代码都是这样写的。
class iteration//迭代器
{
public:
private:
};
迭代人家。
迭代器就是指针。
用迭代器遍历容器。遍历容器底层的数据结构。
容器的作用。
用下标也可以迭代数组。
#include <iostream>
#include <time.h>
using namespace std;
template<typename T>
class myallocator
{
public:
// construct构造 destroy析构
// allocate开辟内存 deallocate释放内存
void construct(void *ptr, const T &val)
{
new (ptr) T(val); //表示在ptr指向的内存,构造一个值为val的对象
}
void destroy(T *ptr)
{
//自己填
ptr->~T();
}
//开辟内存
T* allocate(size_t size)
{
//malloc
return (T*)malloc(size);
}
//释放内存
void deallocate(void *ptr)
{
free(ptr);
}
};
template<typename T, typename Allocator=myallocator<T>>
class Vector
{
public:
//默认构造的vector,底层没分配过内存0
Vector() :mpVec(NULL), mSize(0), mCur(0){}
//size表示初始的内存大小,val表示内存初始值
Vector(int size, const T &val = T())
:mSize(size), mCur(size)
{
mpVec = _allocator.allocate(mSize * sizeof(T));
for (int i = 0; i < mSize; ++i)
{
_allocator.construct(mpVec + i, val);
}
}
//拷贝构造
Vector(const Vector<T> &src)
:mSize(src.mSize), mCur(src.mCur)
{
mpVec = _allocator.allocate(sizeof(T)*mSize);
for (int i = 0; i < mCur; ++i)
{
_allocator.construct(mpVec+i, src.mpVec[i]);
}
}
//operator=
Vector<T>& operator=(const Vector<T> &src)
{
if (this == &src)
return *this;
for (int i = 0; i < mCur; ++i)
{
_allocator.destroy(mpVec+i);
}
_allocator.deallocate(mpVec);
mpVec = _allocator.allocate(sizeof(T)*mSize);
for (int i = 0; i < mCur; ++i)
{
_allocator.construct(mpVec + i, src.mpVec[i]);
}
return *this;
}
~Vector()
{
for (int i = 0; i < mCur; ++i)
{
_allocator.destroy(mpVec + i);
}
_allocator.deallocate(mpVec);
mpVec = NULL;
}
//末尾添加元素 push_front pop_front O(n)
void push_back(const T &val)
{
if (full())
reSize();
_allocator.construct(mpVec + mCur, val);
mCur++;
}
//末尾删除
void pop_back()
{
if (empty())
return;
--mCur;
_allocator.destroy(mpVec + mCur); //把删除的对象一定要析构
}
T front()const{ return mpVec[0]; }
T back()const{ return mpVec[mCur - 1]; }
bool full()const{ return mCur == mSize; }
bool empty()const{ return mCur == 0; }
T& operator[](int index){ return mpVec[index]; }
//内存以2倍方式增长
void reSize()
{
if (mSize == 0)
{
mpVec = _allocator.allocate(sizeof(T));
mSize = 1;
mCur = 0;
}
else
{
T *ptmp = _allocator.allocate(mSize * 2 * sizeof(T));
for (int i = 0; i < mCur; ++i)
{
_allocator.construct(ptmp + i, mpVec[i]);
}
mSize *= 2;
for (int i = 0; i < mCur; ++i)
{
_allocator.destroy(mpVec + i);
}
_allocator.deallocate(mpVec);
mpVec = ptmp;
}
}
int size()const{ return mCur; }
//定义当前容器的迭代器类型 的作用,就是来遍历容器的(遍历容器底层的数据结构)
class iterator
{
public:
private:
};
private:
T *mpVec;
int mSize;
int mCur;
Allocator _allocator;
};
int main(int argc, char* argv[])
{
Vector<int> vec1;
srand(time(0));
for (int i = 0; i < 20; ++i){
vec1.push_back(rand() % 100);
}
int size = vec1.size();
for (int i = 0; i < size; ++i)
{
cout << vec1[i] << " "; // vector 向量容器 operator[] [i] O(1)
}
cout << endl;
/*
需要一种通用的方式,来遍历任何的容器 operator[]做不到的
通用: 怎么通用?是使用方式通用呢?还是所有容器共用一个迭代器呢?
数组operator[]
链表
二维数组
哈希表
红黑树
迭代器和容器是一一对应的,所以在设计上,把迭代器这个类,设计成容器类型的嵌套类性
*/
/*
1.需要在容器里面定义嵌套类性 iterator
2.给容器提供begin方法 iterator begin(); 把容器第0号位元素的迭代器返回回去
3.给容器提供end方法 iterator end(); 把容器末尾元素后继位置的迭代器返回回去
4.给迭代器提供operator!=
5.给迭代器提供operator++()
6.给迭代器提供operator*()
*/
Vector<int>::iterator it = vec.begin();
for (; it != vec.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
return 0;
}
容器迭代器、空间配置器的名字是固定的,不能随意起。
迭代器需要提供的方法:
/*
1.需要在容器里面定义嵌套类性 iterator
2.给容器提供begin方法 iterator begin(); 把容器第0号位元素的迭代器返回回去
3.给容器提供end方法 iterator end(); 把容器末尾元素后继位置的迭代器返回回去
4.给迭代器提供operator!=
5.给迭代器提供operator++()
6.给迭代器提供operator*()
*/
虽然是嵌套类型,但也是两个不同的类。
迭代器的构造方法。
默认构造。
迭代器是指针的引用。
代码要做到高内聚低耦合。降低耦合。不要使用外层的属性。
方法在类体内实现会自动处理成内联。
任何容器都有一个统一遍历的迭代器。统一的方式。
数据的值,是立即数,不能修改的。
底层是动态增长的数组。
给string提供迭代器。
迭代器-->容器
指针-->容器底层的数据结构(封装在迭代器中)
实现vector容器
private:
T*mpVec;
int mSize;
int mCur;
Allocator _allocator;//空间配置器
};
两个迭代器的相减就是指针的相减。
迭代器调用它的减法运算符重载函数。
容器 空间配置器 迭代器
拷贝构造函数
mh
using std::cout;
using std::endl;