第六章 数组、指针与字符串、
指针的赋值
注意有一种特殊的void类型指针可以存储任何类型的对象地址
#include<iostream>
using namespace std;
int main()
{
void *pv;
int i=5;
pv=&i;
int *pint=static_cast<int *>(pv);
cout<<"*pint="<<*pint<<endl;
return 0;
}
故void指针可以在指针所指向的数据类型不确定时使用
空指针:可以用0或者PULL表示
指针数组
例如:
int line1[]={1,0,0};
int line2[]={0,1,0};
int line3[]={0,0,1};
int *pLine[3] = {line1,line2,line3};
表示定义了一个具有三个元素的int 类型指针数组,定义的同时用此三个数组的首地址为这三个元素进行初始化,使每个元素分别指向矩阵的一行
其中pLine[i][j]与*(pLine[i]+j)等价
指针数组和二维数组存在本质上的差异,但二者具有相同的访问形式,例如:
*(*(array2+i)+j)表示二维数组第i行第j个元素值。
用指针作为函数参数:通过在被调函数中直接处理主调函数中的数据而将函数的处理结果返回其调用者,减少函数调用时数据传递的开销。
指针型函数:
将函数指针指向函数,即可以通过函数指针来实现对函数的调用
指向类的非静态成员的指针
访问对象的公有成员的不同方式:
int main()
{
Point a(4,5);
Point *p1 = &a;
int (Point::* funcptr)() const = &point::getX; //定义成员函数指针并初始化
cout<<(a.*funcptr)()<<endl; //使用成员函数指针访问成员函数
cout<<(p1->*funcptr)()<<endl;
cout<<a.getX()<<endl;
cout<<p1->getX()<<endl;
return 0;
}
指向类的静态成员的指针
1、指向类的静态数据成员的指针
例如在类中声明了一个静态数据成员如static int count;,则主函数中指针的定义为:int *ptr = &Point::count;,然后就可以通过指针直接访问静态数据成员cout << *ptr;
2、指向类的静态函数成员的指针
主函数中定义为:void(*funcptr)() = Point::showCount;,然后就可以直接通过指针访问静态函数成员
动态内存分配
动态创建多维数组,例如:
float (*cp)[9][8] = new float[8][9][8];
深复制与浅复制
某些情况下,类内成员变量需要开辟堆内存,浅拷贝就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中一个成员变量指针已经申请了内存,那么A中的那个成员变量也指向同一块内存,这时,如果把B中的内存释放了,A内的指针就成了野指针。
深拷贝是指,类的对象发生复制过程的时候,资源重新分配。
例如:
class Rect
{
public:
Rect() // 构造函数,p指向堆中分配的一空间
{
p = new int(100);
}
~Rect() // 析构函数,释放动态分配的空间
{
delete p;
}
private:
int width;
int height;
int *p; // 指针成员
};
int main()
{
Rect rect1;
Rect rect2(rect1); // 复制对象
return 0;
}
下面是深拷贝:
class Rect
{
public:
Rect() // 构造函数,p指向堆中分配的一空间
{
p = new int(100);
}
Rect(const Rect& r)
{
width = r.width;
height = r.height;
p = new int; // 为新对象重新动态分配空间
*p = *(r.p);
}
~Rect() // 析构函数,释放动态分配的空间
{
delete p;
}
private:
int width;
int height;
int *p;
};