1、对象指针
对象包括数据成员和函数成员。实际只有数据成员才会占用内存。函数成员不会。我们可以通过对象名引用对象,也可以通过地址访问。对象指针就是存储对象地址的变量。
2、this指针
this指针隐含于类的成员函数中,指向成员函数正在操作的对象。构造和析构也同样包含了该指针。它是一个特殊的指针。
class A
{
public:
….
int GetVal(){return x;} //相当于return this->x;
private:
int x;
};
为什么会有这个指针?因为在执行这条语句时编译器要知道返回的x是属于哪一个对象,编译器已经之前已经把对象地址赋值给this指针。调用于隐含这个指针自然就知道了x的所属对象。
一般我们不会直接用到this访问数据成员,有时以对象作为参数传递时会使用this指针。如果写程序时忘记函数名,也可以this->来提示所有的成员函数。
3、指向类非静态成员的指针
可以定义指针指向类的成员,这样可以通过指针直接访问。需要注意的是,指向成员的指针同样只能访问公有数据。语法形式:
类型说明符 类名:: *指针名 //指向数据成员
类型说明符 (类名::*指针名)(形参表) //指向函数成员
赋值语法形式:
指针名=&类名::数据成员
前面我们说过通过‘&’取得地址赋值给指针后就可能通过指针来访问变量了。
但类不同,类声明时并不会为类的数据成员分配内存空间。所以给指向数据成员的指针赋值只是确定该指针指向哪个变量。同时在指针中存放了该数据成员相对于类起始地址的偏移量。
这时的指针明显不能访问到具体数据成员。
声明了类对象这时指针就起作用了。根据对象的起始地址和指向数据成员指针中的偏移量就可以访问到具体数据成员了。
对象名.*指针名
或 对象指针名->*指针名
函数指针与数据成员指针类似。
函数指针名=&类名::成员函数名 //赋值
(对象名.*指针名)(形参) //调用
对象指针名->指针名)()形参
#include<iostream>
using namespace std;
class A
{
public:
A(inta){x=a;}
intGetVal(){return x;}
private:
intx;
};
void main()
{
Aa(8); //声明对象
A*p; //对象指针
int(A::*pGetVal)(); //指向GetVal()的函数指针
p=&a; //对象指针赋值
pGetVal=&A::GetVal; //成员函数指针赋值
cout<<p->GetVal()<<endl;//对象指针调用成员函数
cout<<(a.*pGetVal)()<<endl; //对象调用成员函数指针
//注意调用的语法形式,括号不能去
}
4、指向类静态成员的指针
对于类的静态成员,我们可以用普通指针存放它的地址,通过普通指针访问。
#include<iostream>
using namespace std;
class A
{
public:
A(inta){x=a;}
intGetVal(){count++;return x;}
staticint count;
private:
intx;
};
int A::count=2; //表态数据成员初始化
void main()
{
Aa(8); //声明对象
A*p; //对象指针
int(A::*pGetVal)(); //指向GetVal()的函数指针
p=&a; //对象指针赋值
int*p1=&A::count; //声明int型指针指向静态成员count
pGetVal=&A::GetVal; //成员函数指针赋值
cout<<p->GetVal()<<endl;//对象指针调用成员函数
cout<<(a.*pGetVal)()<<endl; //对象调用成员函数指针
//注意函数指针调用的语法形式,括号不能去
cout<<*p1<<endl;//通过普通指针直接访问
}
//输出8 8 4