13

假设我们有一个 A 类

class A;

和这些类型定义

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);
}
4

6 回答 6

11

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

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

阅读这篇有趣的文章:

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

于 2013-04-17T14:27:45.537 回答
4

考虑以下:

#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在我的系统上)。

于 2013-04-17T14:39:58.657 回答
2

指向成员函数的指针可能是此处C++ FAQ 中指出的数据结构。指向成员函数的指针也是非常奇怪的动物,它提供了一个如何在 Visual C++ 中实现的示例。

于 2013-04-17T14:33:31.257 回答
2

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

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

于 2013-04-17T14:28:25.070 回答
1

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

资料来源:维基百科

这个SO answer 提供了额外的信息

于 2013-04-17T14:29:43.770 回答
0

这里讨论了一个相关的问题: sizeof(some pointer) 是否总是等于四?

请参阅: 指向成员函数的指针是非常奇怪的动物 以获取更多信息。

于 2013-04-17T14:32:47.037 回答