关于类成员函数指针的sizeof

时间:2013-04-17 14:24:16

标签: c++ class pointers sizeof member

假设我们有一个A类

class A;

和这些typedef

typedef void (A::*a_func_ptr)(void);
typedef void (*func_ptr)(void);

我的问题是为什么sizeof(a_func_ptr)返回16,而sizeof(func_ptr)返回4(对于x86系统上的任何指针)?

例如

int main(int argc, char *argv[])
{
  int a = sizeof(a_func_ptr);
  int b = sizeof(func_ptr);
}

6 个答案:

答案 0 :(得分:8)

  

我的问题是为什么sizeof(a_func_ptr)返回16,而sizeof(func_ptr)返回4(对于x86系统上的任何指针)?

因为指向成员的指针的实现方式不同。他们在引擎盖下是不是指针。某些编译器(如MSVC)将它们实现为struct,其中包含多个成员。

阅读这篇有趣的文章:

请注意,在某些编译器中,它们可能具有相同的大小。底线是:它们依赖于编译器。

答案 1 :(得分:2)

请考虑以下事项:

#include <iostream>

class A {
public:
    virtual void foo(){ std::cout << "A::foo" << std::endl; }
    void bar(){ std::cout << "A::bar" << std::endl; }
};

class B : public A {
public:
     void foo(){  std::cout << "B::foo" << std::endl; }
     void bar(){ std::cout << "B::bar" << std::endl; }
};

typedef void (A::*a_func_ptr)(void);

int main() {
   a_func_ptr f = &A::foo;
   a_func_ptr g = &A::bar;
   B b;
   A a;
   (b.*f)();
   (b.*g)();
   (a.*f)();
   (a.*g)();
}

输出:

B::foo
A::bar
A::foo
A::bar

两个成员指针的类型相同,但在每种情况下都正确地路由了调用。

不知何故,当指向方法的指针实际上是简单方法虚拟方法时,生成的程序必须知道。因此,方法指针的运行时表示必须包含更多信息来处理第二种情况。

备注:大小似乎与实现有关(我的系统上有8)。

答案 2 :(得分:1)

类的指针到成员函数不像常规指针那样保存“确切地址”。它存储的信息比常规函数指针多。

因此,当您使用sizeof来测量类的指针到成员函数的大小时,您不应期望它与常规函数指针的大小相同。

答案 3 :(得分:1)

  

虽然C和C ++中的函数指针可以很简单地实现   地址,通常sizeof(Fx)== sizeof(void *),成员   C ++中的指针通常被实现为“胖指针”,通常是两个   或者是简单函数指针大小的三倍,以便处理   虚拟继承。

来源:Wikipedia

SO answer offers additional information

答案 4 :(得分:1)

指向成员函数的指针可能是C ++ FAQ here中指出的数据结构。另外Pointers to member functions are very strange animals提供了如何为Visual C ++实现它的示例。

答案 5 :(得分:0)