类成员函数大小问题

来源:互联网 发布:网络卫星直播电视 编辑:程序博客网 时间:2024/05/11 19:42

 上周,我一同事,在调试我们项目的时候,发现我写的一段代码中,有一个类成员函数指针数组有大小有点怪异,便叫我过去瞧瞧。有如下一段定义:

 

interface IPLUnknown
{
  virtual ~IPLUnknown() {}
};

 

interface IPLRunnable : public IPLUnknown
{
  virtual BOOL  Init(void) = 0;
  ……
};

 

class CThread;
typedef void (CThread:: *CALLBACK)(const SMsg * const pMsg);

 

class CThread : public IPLRunnable
  ,public TPLSingleton<CThread>

{

  ……

  CALLBACK           m_mapHandler[MAX_MAP];

  ……

};

其中,IPLRunnable 是一个纯虚类,MAX_MAP为11,但是在调试的时候,却在Visual C++中看到m_mapHandler的数组个数为22,而sizeof(m_mapHandler[0])为4,sizeof(m_mapHandler)为88,我的那位同事感觉很奇怪。在32位机上,sizeof(m_mapHandler[0])为4是可以理解,但为什么是分配的是22个数组大小,总和为88字节的空间。根据我的经验,我没有理会VC调试器给我们的信息,而是在代码中添加了一些打印输出语句;经过打印输出显示,sizeof(m_mapHandler[0])为8,而不是VC调试器中所显示的4;因此,数组总大小为88个字节,是正确的,只是调试器显示错误罢了。现在问题的焦点转向了什么sizeof(m_mapHandler[0])为8,而不是4?经过测试,我们发现,如果将public IPLRunnable注释掉,则sizeof(m_mapHandler[0])为4,原来是纯虚基类所致。后来我们还将public IPLRunnable改为virtual public IPLRunnable测试sizeof(m_mapHandler[0])则为12,这个比较特别,根据编译器的不同也有所不同。为证实是因编译器而异, 我分别在LINUX下用GCC编译输出,以及在WINDOWS下用MINGW下的GCC编译输出,sizeof(m_mapHandler[0])均为8。值得一提的是,在用GCC编译的程序中,不管是public IPLRunnable还是virtual public IPLRunnable,sizeof(m_mapHandler[0])均为8。

 

总结:

    在VC中,类成员函数指针随基类不同而不同,如果派生类是普通派生于基类,且基类有纯虚函数,则单个指针大小为8字节(32位下);如果基类有纯虚函数,且在派生时,加了virtual关键字,则单个指针大小为12个字节;否则单个指针大小为4字节。

    在GCC中,类成员函数指针不随基类的变化而变化,单个指针大小均为8个字节。

 

 

原创粉丝点击