一、堆区创建数据和数组
首先new的返回类型一定是指针
数据:也就是变量
void test01()
{
//在堆区创建整型数据
//new返回的是该数据类型的指针
int * pointer = new int(variable);
cout << * pointer << endl; //varible的数据
cout << pointer << endl; //堆区某个地址
//堆区的数据由程序员开辟,程序员释放,如果想释放,则用delete
delete p;
//cout << *p << endl;已经被释放,再操作就非法
}
一维数组:
void test02()
{
int * Array = new int[length];
//new int (10)是数据10;new int[length]是数组有length那么长度
for (int i = 0; i < length; i++)
{
Array[i] = i + 100; //给length个元素赋值
}
for (int i = 0; i < length; i++)
{
cout << Array[i] << endl;
}
//释放数组要加[],
delete[] arr;
}
二维数组:以创建对象数组为例,因为虚基类继承的子对象不同,所以想要创建对象数组直接不行,所以在数组内部放对象指针,每个指针指向子类的对象。
三个指针要搞清楚:Header_Array是虚基类的对象里面用来维护一个二维数组的指针
Array是cpp中二维数组的指针,可以理解为是Header_Array指针的临时存放点
TempPointer是Header_Array数组里面装载的指针,TempPt指向创建的每一个具体对象(Kevin和Luxy)
背景:Base是虚基类,Son1和Son2是子类,继承于Base
Header_Array数组里面存放的是不同的指针,所以用二维指针来维护
Base ** Header_Array;
//源文件
Base ** Array = new Base*[length]; //比一维指针多了一个*
///。。。省略
//存放指针
Base * tempPointer1 = new Son("kevin", 20, 185);
Base * tempPointer2 = new Daughter("Luxy", 21, 166);
Array[0] = tempPointer1;
Array[1] = tempPointer2;
//释放原来
delete[] Header_Array;
//更新指向
Header_Array = Array;
二、删除对象数组的方法(析构函数)
先删除对象数组中每个元素,再删除维护的数组。
System::~System() //因为增加了Header_Array需要结束后释放
{
//先清除每一个数组中的元素,在清除整个数组
if (this->Header_Array != NULL)
{
for (int i = 0; i < this->Num; i++)
{
if (this->Header_Array[i] != NULL)
{
delete this->Header_Array[i];
}
}
this->Num = 0;
delete[] this->Header_Array;//结束释放内存指针
this->Header_Array = NULL;
}
}
三、读写文件中的内容
读文件需要用到文件流创建对象: ifstream; 写文件:ofstream
3.1 按每个单词读,以空格为分割
需要数组来存放读取的信息。
ifstream ifs;//ifs是ifstream创建的对象
int info;
string str;
int integerArray[100] = {0}; //存放读取的信息
string stringArray[10];
//判断文件读取成功标志,默认添加
ifs.open("文件路径\\data.txt", ios::in);
if(!ifs.is_open ())
{cout << "Open file failure" << endl;}
//单个读取
for (int i=0; !ifs.eof() ;i++) //一直读取到文件结尾
{
ifs >> info;
integerArray[i] = info;
}
ifs.close();
//跨行读取
while (ifs >> info1 && ifs >> info2 ...)
{
//可以读出文件中的每一行信息
//每一行用空格分割的文件装进了info1,info2中
//可以直接使用
number++; //可以统计有多少行信息
}
ifs.close();
3.2 按行读,以换行为分割
用getline方法第一个参数是流对象,第二个是存放行信息的容器,因为按行读会把空格也给读进去所以用字符串来装。
for ( int i = 0; !ifs.eof(); i++)
{
getline(ifs, str); //碰到换行才退出识别文件
num = i; //统计多少行信息
}
ifs.close();
3.3 写入文件
ofstream ofs;
ofs.open("FILENAME", ios::out);
//打开文件可以用out,也可以用app
//app直接在文件末尾追加
for (int i = 0; i < Number; i++)
{
ofs << Array[i]->m_Id << " "
<< Array[i]->m_Name << " " << endl;
}
cout << "成功保存" << endl;
ofs.close();
四、头文件防止重复编译
防止重复定义报错:redefination of “class”
在添加头文件的区域再次添加:
#pragma once
五、创建对象的指针
不能直接定义对象指针,只能直接定义一个对象,有两个方法:
1.在堆区创建 2.指向栈上的对象
1.堆区直接创建
Base * arr = new Base ;//在堆区直接创建对象指针arr
delete arr;
2.创建对象,再指向对象
Base object1; //创建对象
Base * arr = &object1;
3.多态,创建子类继承于父类的指针
Base * arr = new Son(“kevin”,12,185);
delete arr;
4.模板类
template<class NameType, class ageType>
class Base{}
Base<string, int> p1("Kevin", 12, 185);
Base<string, int> *arr = &p1;