本文所才用的编译环境是VC++6.0
作用
指向data members的指针,是一个有点神秘但颇有用处的语言特性,特别是如果需要详细调查 class members的底层布局的话,这样的调用可以决定vptr是放在 class 的起始位置或是尾端.另一个用途,可用来决定 class 中的access sections的次序
来看一个TEST类 不带虚函数
class TEST
{
public:
int nX;
int nY;
int nZ;
double dJ;
};
下面对该类进行测试
// Test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, char* argv[])
{
cout<<sizeof(TEST)<<endl;
int TEST::* p = &TEST::nX;
printf("offest nX = %d\n", p);
cout<<"offest nX = "<<p<<endl;
p = &TEST::nY;
printf("offest nY = %d\n", p);
cout<<"offest nY = "<<p<<endl;
p = &TEST::nZ;
printf("offest nZ = %d\n", p);
cout<<"offest nXZ = "<<p<<endl;
p = NULL;
printf("offest NULL = %d\n", p);
cout<<"offest NULL = "<<p<<endl;
double TEST::* pD = &TEST::dJ;
printf("offest dJ = %d\n", pD);
cout<<"offest dj = "<<pD<<endl;
return 0;
}
测试结果
①sizeof大小 就是结构体的内存对齐24 没什么好讲的
②printf的结果可以看出 nX nY nZ dJ的偏移量 就是按照他们在类声明的时候的顺序排列的
③一个指向NULL的Data Members的指针 他的offset 会被编译器置-1
④为什么cout输出的 只有0/1 因为输出的是一个bool值,代表有无偏移
*****************************************************
下面加上虚函数,来判断虚函数指针的摆放位置
class TEST
{
public:
int nX;
int nY;
int nZ;
virtual void Fun(void);
};
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, char* argv[])
{
cout<<sizeof(TEST)<<endl;
int TEST::* p = &TEST::nX;
printf("offest nX = %d\n", p);
cout<<"offest nX = "<<p<<endl;
p = &TEST::nY;
printf("offest nY = %d\n", p);
cout<<"offest nY = "<<p<<endl;
p = &TEST::nZ;
printf("offest nZ = %d\n", p);
cout<<"offest nXZ = "<<p<<endl;
p = NULL;
printf("offest NULL = %d\n", p);
cout<<"offest NULL = "<<p<<endl;
return 0;
}
结果
结论
①我们可以看出 虚指针是放在类的非成员变量的上边,无论他声明的位置
②为什么加了虚函数后,printf的offest NULL就变成了0