template
class MyArray
{
public:
MyArray()
{
memroy = new _Ty[size];
//new MM[size]
}
_Ty& operator[](int index)
{
return memroy[index];
}
~MyArray()
{
delete[] memroy;
}
public:
_Ty* begin()
{
return memroy + 0;
}
_Ty* end()
{
return memroy + size;
}
//类的对象模仿指针的行为
class iterator
{
public:
iterator(_Ty* pmove = nullptr) :pmove(pmove) {}
void operator=(_Ty* pmove)
{
this->pmove = pmove;
}
bool operator!=(_Ty* pmove)
{
return this->pmove != pmove;
}
iterator operator++(int)
{
this->pmove++;
return *this;
}
_Ty operator*()
{
return pmove[0];
}
protected:
_Ty* pmove;
};
protected:
_Ty* memroy; //MM
};
void testMyArray()
{
MyArray array1D;
for (int i = 0; i < 3; i++)
{
array1D[i] = i;
}
MyArray::iterator iter;
for (iter = array1D.begin(); iter != array1D.end(); iter++)
{
cout << *iter << "\t";
}
cout << endl;
}
①不推荐new一个array对象出来,因为还需要自己自行释放,就直接用对象,其可以自行管理内存
②直接用数组下标法访问
③本质是类模板,必须进行显式调用。
void testArray()
{
//存储数据的类型是:int
//数组长度:3
//用模板的时候用的都是对象,而不是new一个对象
array array1D;
array* p = new array;
delete p;
#define MAX 5
array dAarray1D;
//创建并初始化
array num = { 1,2,3 };
for (int i = 0; i < array1D.size(); i++)
{
array1D[i] = i;
}
}
①empty():判断容器是否为空,和通过 size()==0 的判断条件功能相同,但其效率可能更快。
②size():
③fill():将容器中所有的元素填充为同一个数字。
④迭代器for循环遍历的写法
⑤swap()函数:需要长度一致。
void testExOperator()
{
//使用: 和数组一样的用法
//一些函数
array test = { 1,2,3 };
cout << test.empty() << endl;
cout << test.size() << endl;
test.fill(5); //填充所有的元素 ,填充为5
for (int v : test)
{
cout << v << "\t";
}
cout << endl;
//交换 长度一定是要一样常
array test1 = { 0,0,0};
test.swap(test1);
int cData[3] = { 1,2,3 }; //映射:一种对应关系,数组下标对应元素
for (auto v : cData)
{
cout << v << "\t";
}
cout << endl;
}
①正常开一个定长自定义数据类型的array时,需要一个无参的构造函数(因为其内部实现用的new是无参构造方式)
②赋值时由于[ ]被重载了,可以采用方括号法来进行等于=赋值 ,在采用for(auto val: array名)遍历。
①begin()永远指向第一个元素的位置
②end()指向最后一个元素后一个的位置(小心越界访问!!!)(一般采用*(迭代器名称.end()-1)来访问最后一个元素)
③用对象模仿指针的行为=>所以*号加上迭代器就是进行取值运算
④迭代器进行遍历的方法。(可以用点运算符进行访问(需要加上*),也可以用箭头->来访问)
//定长数组处理自定义类型的数据
class MM
{
public:
MM() {}
MM(string name, int age) :name(name), age(age) {}
void print()
{
cout << name << "\t" << age << endl;
}
protected:
string name;
int age;
};
void testUserData()
{
array mmData; // MM array[3];
for (int i = 0; i < mmData.size(); i++)
{
string name = "name";
mmData[i] = MM(name + to_string(i), 16 + i);
}
for (auto v : mmData)
{
//v:就是MM的对象
v.print();
//cout<::iterator iter;
//begin()
//end(): 最后一个位置,不是最后元素的位置
(*mmData.begin()).print();
//(*mmData.end()).print(); 越界访问
(*(mmData.end() - 1)).print();
for (iter = mmData.begin(); iter != mmData.end(); iter++)
{
//(*iter).print();
iter->print();
//cout<<*iter; //重载<<
}
}
//array当做函数参数,返回值都可以
array& returnArray(array& temp)
{
for (int i = 0; i < temp.size(); i++)
{
temp[i] = i;
}
return temp;
}
vector vecDate;
这种方式,只能用成员函数做插入(尾插法)
vector.push_back(666);
vector strDate(3);//默认为0
确定长度的好处:可以直接使用数组下标法插入(只有在确定长度范围以内才可以,若超过的必须采用成员函数进行插入)->否则vector subscript out of range(数组下标越界)可以在push_back在原内存的后面进行扩增。
for(int i=0;i<3;i++)
{
string name="name";
strDate[i]=name+to_string(i);
}
vector dDate={1.1,1.3,1.5};
vector::iterator iter;
for(iter=strData.begin();iter!=strData.end();iter++)
{
cout<<*iter<<"\t";
}
区别于array(不需要无参构造函数!!!)->所以在vector中可以先声明,但实际没有申请内存。
主要就是输入输出的时候需要进行重载一下。
①size(): 当前容器中元素的个数
②empty(): 判断是否为空
③front():访问第一个元素
④back():访问最后一个元素
⑤at(int i):利用下标访问 iDate.at(2)等效于 iDate[2];
⑥emplace(参数1,参数2):修改函数,参数1参入应该是一个元素(‘地址’),参数2传入的是需要修改成的值
(正确写法) //修改下标为2的值为100
vector iDate={1,2,3,4};
iDate.emplace(iDate.begin()+2,100);
(错误写法)
vector iDate={1,2,3,4};
iDate.emplace(&iDate[2],100);
没有进行相应的重载(别老想着当指针用了()所有的容器都是用迭代器来描述位置的。
⑦emplace_back(参数):在尾部添加一个元素(扩增)
注:无emplace_front()
⑧删除函数
⑨批量复制:assign()函数
int array[]={1,2,3};
vector vecDate;//无需起始长度
vecDate.assign(array,array+3);
1.array和array的嵌套
void testArrayVsArray()
{
array, 4> arrData; //int arrData[4][3]
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 3; j++)
{
arrData[i][j] = i * j;
cout << arrData[i][j] << "\t";
}
cout << endl;
}
}
2.vector和vector的嵌套(通常用的push_back一个temp vector->可以生成不等列长的二维数组,所以遍历的时候常用size()) ()
void testVectorVsVector()
{
srand((unsigned int)time(nullptr));
vector> vecData;
//一般vecotor 采用的是push_back插入
for (int i = 0; i < 4; i++)
{
vector temp;
//rand()%3 [0,2] [2,4]
for (int j = 0; j < rand()%3+2; j++)
{
temp.push_back(i * j);
}
vecData.push_back(temp);
}
//不等列数的二位数组
for (int i = 0; i < vecData.size(); i++)
{
for (int j = 0; j < vecData[i].size(); j++)
{
cout << vecData[i][j] << "\t";
}
cout << endl;
}
}
3.array中嵌套vector
void testArrayVsVector()
{
array, 3> vecArr;
vector vec1[3] = { { 1,2,3 } , {1,2,3,4}, {1,2}};
for (int i = 0; i < vecArr.size(); i++)
{
vecArr[i] = vec1[i];
}
//不等列数的二位数组
for (int i = 0; i < vecArr.size(); i++)
{
for (int j = 0; j < vecArr[i].size(); j++)
{
cout << vecArr[i][j] << "\t";
}
cout << endl;
}
vector, 3>, 3>> vec;
//慢慢剥洋葱即可
array, 3>, 3> test;
for (int i = 0; i < 3; i++)
{
test[i] = vecArr; //vecArr: array, 3>
}
vec.push_back(test);
vector, 3>, 3>> test;
//上面一行 等效下面两行
using Data = array, 3>, 3>;
vector test2;
array, 3>, 3> test3;
//上面一行 等效下面两行
using Data2 = array, 3>;
array test3;
}
4.vector中嵌套array(慢慢剥洋葱即可)(解析过程,可以用using语法起别名来理解简化)
using Date=array<.......> 实际开发中一般不会交叉嵌套,上限3层较多。
void testVectorVsArray()
{
vector> arrVec;
array arr[3] = { { 1,2,3 } , {1,2,3}, {1,2,3}};
for (int i = 0; i < 3; i++)
{
arrVec.push_back(arr[i]);
}
for (int i = 0; i < arrVec.size(); i++)
{
for (int j = 0; j < arrVec[i].size(); j++)
{
cout << arrVec[i][j] << "\t";
}
cout << endl;
}
}