原文:https://blog.csdn.net/laojiu_/article/details/68946915
(原文有笔误)
1.
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
class A
{
public:
A(int a=0,int b=0):a(a),b(b){}
void print()
{
cout<<"a="<<a<<" "<<"b="<<b<<endl;
}
public:
int a;
int b;
};
typedef void (A::*pFun)(void);
int main(void)
{
A ap;
ap.print();//输出a和b的默认值
int A::*aptr=&A::a;//aptr为A这个类中,a的成员指针
int A::*bptr=&A::b;bptr为A这个类中,b的成员指针
printf("aptr=%d,bptr=%d\n",aptr,bptr);//输出两个指针值
ap.*bptr=5;//通过成员指针修改成员的值
ap.print();
return 0;
}
类成员变量指针,实际上并不是真正意义上的指针,即它并不是指向内存中某个地址,而是该成员变量与对象指针的偏移量。该偏移量只有附着在某个具体对象,才能指向对象成员变量的具体地址。
2.对于C++静态成员的指针,其值就是指向内存中数据区某个地址,就是真正意义上的指针,因为静态成员属于类范围,不属于某个对象。
成员函数指针
1.非静态函数指针
C++非静态成员函数的指针,其值就是指向一块内存地址。但是指针不能直接调用,它需要绑定到一个对象才能调用。
2.虚拟成员函数指针
虚拟成员函数指针的值表示该函数在虚函数表中,离表头的偏移量+1。通过反汇编代码知道当一个对象调用虚拟函数时,主要是通过
- 获取指向虚函数表指针的值。
- 指向虚函数表指针的值加上虚函数离表头的偏移量即为该函数的地址。
所以虚函数表示虚函数在虚函数表的偏移量+1,再绑定到一个对象,即可调用这个虚函数。
谈谈我对这些指针本质上的理解。
一个类,当它编译,运行,实例化一个对象时,在内存中总是可以找到该对象的所有成员变量和函数地址。
非静态成员通过对象指针+偏移量访问。
虚函数可以通过对象指针加偏移量得到。
静态成员,非静态函数,静态函数可以通过链接时获得。
所以:
非静态成员指针表示一个偏移量,因为通过对象可以访问到。
虚函数指针表示虚函数地址在虚函数表中的偏移量。
静态成员,非静态函数和静态函数不能通过对象指针直接访问到,所以这三个的指针类型必须是具体的函数地址。