C++中new和delete在数组指针和指针数组中的调用
首先,先区分下数组指针和指针数组:
数组指针(也称行指针)
标准格式:A (*p)[num]
(A为数据类型,num为无符号整数)
解释:因为()优先级别高,所以我们可以看出(*p)是一个一维指针,
把(*p)看作整体 ,从(*p)[num]我们可以看出它是一个一维的数组指针,
并且是A数据类型的,num表示该指针的步长, 所以p+1表示指针跳过num个元素,
在实践中,我们常拿来这样用:int (*p)[3] = new int[2][3];
所以p + 1跳过了第一行2个元素从而指向下一行的第一个元素p[1][0],故而称作行指针.
指针数组
参考格式: A *p[num];
(A为数据类型,num为无符号整数)
[ ]优先级高,先与p结合成为一个数组,再由A*说明这是一个A数据类型的指针数组,
它有n个指针类型的数组元素。
这里执行p+1是错误的,这样赋值也是错误的:p=a;
因为p是个不可知的表示,只存在p[0]、p[1]、p[2]...p[n-1],而且它们分别是指针变量可以用来存放变量地址。
但可以这样 *p=a; 这里*p表示指针数组第一个元素的值,a的首地址的值。
如要将二维数组赋给一指针数组:
int *p[3];
int a[3][4];
for(i=0;i<3;i++)
p[i]=a[i];
这里int *p[3] 表示一个一维数组内存放着三个指针变量,分别是p[0]、p[1]、p[2]
所以要分别赋值。
介绍完数组指针和指针数组后,我们用一个ClassA类的new分配和delete来说明使用示例:
//ClassA.h
#ifndef H_ClassA #define H_ClassA #include<iostream> using namespace std; class ClassA { public: ClassA(): m_ObjectIndex(m_ObjectNum) { m_ObjectNum++; cout << "ClassA:构造函数" << endl; }; virtual ~ClassA(){ m_ObjectNum--; cout << "ClassA:析构函数" << endl; }; void coutObjectIndex() const { cout << "ClassA对象索引:" << m_ObjectIndex << endl; } void coutObjectNum() const { cout <<"ClassA对象数量:" <<m_ObjectNum << endl; } private: int m_ObjectIndex; public: static int m_ObjectNum; }; int ClassA::m_ObjectNum = 0; #endif
//main.cpp
#include<iostream> using namespace std; #include "ClassA.h" int main(char argc, char* argv[]) { //------------【前三组对象】---------------- ClassA a; //初始一个类对象 a.coutObjectIndex(); a.coutObjectNum(); a.~ClassA(); //直接调用析构函数释放对象内存空间 cout << endl; ClassA* p = new ClassA; //指针指向一个new分配的对象首地址 p->coutObjectIndex(); p->coutObjectNum(); delete p; //用delete释放对象堆空间 cout << endl; ClassA* point = new ClassA[2]; //用new分配10个对象,并用指针指向首地址 for (size_t i = 0; i < 2; i++) point[i].coutObjectIndex(); point->coutObjectNum(); delete[] point; //delete释放数组形式的对象队空间 cout << endl; //----------------【数组指针】------------------- ClassA(*arrPoint)[3] = new ClassA[2][3];//用new分配2*3个对象,并用指定列数为3的数组指针指向首地址 for (size_t i = 0; i < 2; i++) arrPoint[i]->coutObjectIndex(); for (size_t i = 0; i < 2; i++) for (size_t j = 0; j < 3; j++) arrPoint[i][j].coutObjectIndex(); arrPoint[0][0].coutObjectNum(); delete arrPoint; //数组指针其实是一个指针, 其指向是一片连续的堆空间,调用一次即可 cout << endl; //---------------【一维指针数组】---------------- ClassA* pointArr[3]; //构建维度为3的指针数组,并使其每一个元素指向一个new分配2维数组对象的首地址 for (size_t i = 0; i < 3; i++) { pointArr[i] = new ClassA[2]; for (size_t j = 0; j < 2; j++) pointArr[i][j].coutObjectIndex(); } pointArr[0]->coutObjectNum(); for (size_t i = 0; i < 3; i++) //对指针数组每一个元素指针,调用 delete[] delete[]pointArr[i]; cout << endl; //---------------【指向指针数组的二维数组】--------- ClassA** twoDimPoint = new ClassA*[3]; //用new分配一个3维的指针数组对象,并用二维指针对象指向它的首地址 (*twoDimPoint)->coutObjectNum(); for (size_t i = 0; i < 3; i++) { twoDimPoint[i] = new ClassA[2]; //继续用new分配2维的对象,并用指针数组元素指向首地址 for (size_t j = 0; j < 2; j++) twoDimPoint[i][j].coutObjectIndex(); } twoDimPoint[0][0].coutObjectNum(); for (size_t i = 0; i < 3; i++) //对一维指针数组每一个元素指针,调用 delete[] delete[] twoDimPoint[i]; delete[] twoDimPoint; //释放二维指针所分配的堆空间 cout << endl; cout <<"为验证所有对象清理完毕, 输出最后剩余对象数量:"<<ClassA::m_ObjectNum<<endl; getchar(); return 0; }
main.cpp中注释说的比较清楚,相信大家能理解,这里我就不做过多说明了~
最后附上程序结果图,大家自己也可以运行看看:
【前三组对象】:
【数组指针】:
【一维指针数组】:
【指向指针数组的二维数组】:
- 上一篇: shiro实现系统的退出功能
- 下一篇: 销毁new的指针