# include <iostream>
using namespace std;
//类对象的成员变量、成员函数内存测试
class Base
{
public: //成员函数
void foo1()
{
}
void foo2()
{
}
public: //成员变量
double m_fMember1;
int m_nMember2;
};
typedef void (Base::*P) (); //定义类成员函数指针类型,用于得到类的成员函数指针
int main()
{
Base base;
cout<<"类对象的地址是:"<<&base<<endl;
cout<<"类对象成员变量m_fMember1的地址是:"<<&(base.m_fMember1)<<endl;
cout<<"类对象成员变量m_fMember1的占用的内存字节数是:"<<sizeof(base.m_fMember1)<<endl;
cout<<"类对象成员变量m_nMember2的地址是:"<<&(base.m_nMember2)<<endl;
// cout<<"Base类第一个成员函数的地址是:"<<&Base::foo1<<endl;
// cout<<"Base类第二个成员函数的地址是:"<<&Base::foo2<<endl;
P pFunc = &Base::foo1;
unsigned int* tmp = (unsigned*) &pFunc;
cout<<"Base类第一个成员函数的地址是:"<<hex<<*tmp<<endl;
pFunc = &Base::foo2;
tmp = (unsigned*)&pFunc;
cout<<"Base类第二个成员函数的地址是:"<<hex<<*tmp<<endl;
return 0;
}
结果:
类对象中的成员变量是按照类声明中的顺序依次排列的,而类对象的成员函数则不是。因为每个对象都有一份成员变量不同,而并不是每个对象都有一份成员函数。因为同一个类的所有对象的成员函数都是相同的,没有必要为每个对象都配备一份成员函数。因此类的所有成员函数都被放在一个特殊的位置,所有这个类的对象都共用这份成员函数。总结:类的对象中每个对象有各自的成员变量,并共用类的成员函数。
若类中有虚函数存在,情况有一些变化。为了能让对象能够调用它的虚函数,在每个对象最开始的内存位置添加一个虚函数表的指针_vfptr,其后才是对象的成员变量内存数据;如果某个类是个派生类,那么它的对象内存中最开始的地方实际上是基类对象的拷贝, 包括基类虚函数表指针和成员变量,其后才是派生类自己的成员变量数据。