关于类成员函数指针的sizeof [重复]

问题描述 投票:10回答:6

这个问题在这里已有答案:

假设我们有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);
}
c++ class pointers sizeof member
6个回答
8
投票

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

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

阅读这篇有趣的文章:

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


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)。


1
投票

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

资料来源:Wikipedia

SO answer offers additional information


1
投票

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

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


1
投票

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


0
投票

这里讨论一个相关的问题:Is the sizeof(some pointer) always equal to four?

有关详细信息,请参阅:Pointers to member functions are very strange animals

© www.soinside.com 2019 - 2024. All rights reserved.