Part6 数组、指针与字符串 6.8对象指针 6.9动态内存分配
6.8对象指针
如: Point a(5,10); Piont *ptr; ptr = &a;
通过指针访问对象成员:
ptr->getX() 相当于 (*ptr).getX();
//例6-12使用指针来访问Point类的成员 #include<iostream> using namespace std; class Point{ public: Point(int x = 0, int y = 0):x(x),y(y){} int getX() const {return x;} int getY() const {return y;} private: int x,y; }; int main(){ Point a(4,5); Point *p1 = &a;//定义对象指针,用a的地址初始化 cout << p1->getX() << endl;//用指针访问对象成员 cout << a.getX() << endl;//用对象名访问对象成员 return 0; }
this指针:指向当前对象自己
隐含于类的每一个非静态成员函数中。
曾经出现过的错误例子 class Fred; //前向引用声明 class Barney { Fred x; //错误:类Fred的声明尚不完善 }; class Fred { Barney y; }; 正确的程序 class Fred; //前向引用声明 class Barney { Fred *x; }; class Fred { Barney y; };
6.9动态内存分配
1 动态申请内存操作符 new
new 类型名T(初始化参数列表)
功能:在程序执行期间,申请用于存放T类型对象的内存空间,并依初值列表赋以初值。
结果值:成功:T类型的指针,指向新分配的内存;失败:抛出异常。
释放内存操作符 delete
delete 指针p
功能:释放指针p所指向的内存。p必须是new操作的返回值
//例6-16 动态创建对象举例 #include<iostream> using namespace std; class Point{ public: Point():x(0),y(0){ cout << "Default Constructor called." << endl; } Point(int x, int y):x(x),y(y){ cout << "Constructor called." << endl; } ~Point(){cout << "Destructor called." << endl;} int getX() const {return x;} int getY() const {return y;} void move(int newX, int newY){ x = newX; y = newY; } private: int x,y; }; int main(){ cout << "Step one: " << endl; Point *ptr1 = new Point;//调用默认构造函数 delete ptr1;//删除对象,自动调用析构函数 cout << "Step two: " << endl; ptr1 = new Point(1,2); delete ptr1; return 0; }
2 分配和释放动态数组
分配:new 类型名T [ 数组长度 ]
数组长度可以是任何表达式,在运行时计算
释放:delete[] 数组名p
释放指针p所指向的数组。
p必须是用new分配得到的数组首地址。
//例6-17 动态创建对象数组举例 #include<iostream> using namespace std; class Point{ public: Point():x(0),y(0){ cout << "Default Constructor called." << endl; } Point(int x, int y):x(x),y(y){ cout << "Constructor called." << endl; } ~Point(){cout << "Destructor called." << endl;} int getX() const {return x;} int getY() const {return y;} void move(int newX, int newY){ x = newX; y = newY; } private: int x,y; }; int main(){ Point *ptr = new Point[2];//创建对象数组 ptr[0].move(5,10);//通过指针访问数组元素的成员函数 ptr[1].move(15,20);//通过指针访问数组元素的成员函数 cout << "Deleting..." << endl; delete[] ptr;//删除整个对象数组 return 0; }
//动态创建多维数组 #include<iostream> using namespace std; int main(){ int (*cp)[9][8] = new int[7][9][8];//cp是指向9*8的二维数组的指针 for(int i = 0; i < 7; i++) for(int j = 0;j < 9; j++) for(int k = 0; k < 8; k++) *(*(*(cp + i)+ j)+ k) = (i*100 + j*10 + k);//可以写成cp[i][j][k] for(int i = 0; i < 7; i++){ for(int j = 0;j < 9; j++){ for(int k = 0; k < 8; k++) cout << cp[i][j][k] << " "; cout << endl; } cout << endl; } delete[] cp; return 0; }
3 将动态数组封装成类
//6-18动态数组类 #include <iostream> #include <cassert> using namespace std; class Point{ public: Point():x(0),y(0){ cout << "Default Constructor called." << endl; } Point(int x, int y):x(x),y(y){ cout << "Constructor called." << endl; } ~Point(){cout << "Destructor called." << endl;} int getX() const {return x;} int getY() const {return y;} void move(int newX, int newY){ x = newX; y = newY; } private: int x,y; }; class ArrayOfPoints{//动态数组类 public: ArrayOfPoints(int size):size(size){ points = new Point[size]; } ~ArrayOfPoints(){ cout << "Deleting..." << endl; delete[] points; } Point& element(int index){//element函数来取数组的元素 assert(index >= 0 && index < size);//下标不能越界 return points[index];//返回引用可以用来操作封装数组对象内部的数组元素,返回值则不能 } private: Point *points;//指向动态数组首地址 int size; }; int main(){ int count; cout << "Please enter the count of points: "; cin >> count; ArrayOfPoints points(count);//创建数组对象 points.element(0).move(5,0);//访问数组元素的成员 points.element(1).move(15,20); return 0; }