关于 sizeof 和类成员函数的问题

A question about sizeof and class member function

提问人:MainID 提问时间:2/18/2009 最后编辑:MainID 更新时间:2/19/2009 访问量:2119

问:

 class B
{
   public:
     int a;
     void fn();
}

如果我创建一个 B 的对象,使用

B* pb = new B;

fn() 的内存在哪里?

对象中是否有指向 fn() 的内存定位的指针?

如果是,为什么 sizeof(B) 返回值,就好像对象中根本没有指针一样?

C++ 大小的

评论


答:

2赞 SmacL 2/18/2009 #1

只会为虚函数(在 vtable 中)存储指针,而不会为非虚函数存储指针。

15赞 Konrad Rudolph 2/18/2009 #2

fn() 的内存在哪里?

由于它是一个普通函数,因此位于程序的代码部分的某个位置。对于类的所有实例,此位置都是相同的。事实上,它与 via 的实例化无关。Bpb

对象中是否有指向 fn() 的内存定位的指针?

不。对于普通的成员函数,这不是必需的,因为地址在编译时(或最迟在链接时)是已知的;因此,它不必在运行时单独存储。

对于虚拟功能,情况就不同了。虚函数指针存储在数组中(简称为“虚函数指针表”或简称“vtable”)。每个类都有一个这样的 vtable,每个指向类的实例都存储一个指向该 vtable 的指针。这是必要的,因为如果类型的指针/引用指向一个子类,编译器就无法知道要调用哪个函数;相反,正确的函数是在运行时通过在关联的 VTABLE 中查找来计算的。vtable 指针在对象中也很明显。BaseDerivedsizeof

评论

0赞 David Thornley 2/18/2009
如果 fn() 是虚拟的,则在某处将有一个内存部分(称为 vtable),其中包含指向 B::fn() 的指针。类只有一个,每个类对象没有一个,因此不会显示在 sizeof(B) 中。
0赞 Konrad Rudolph 2/19/2009
大卫:嗯。每个类只有一个 vtable,true。但是,每个实例都包含指向该 vtable 的指针,并且指针大小确实显示在 中。我会澄清这一点。sizeof(B)
1赞 Sasha 2/18/2009 #3

1) B* pb = new B 将在堆上分配内存。这意味着,除其他事项外,您需要通过删除运算符自行清理它。或者,您可以将指针放在智能指针(shared_ptr,auto_ptr scope_ptr)中,让它进行清理。

2)因为指针是类型,指向一个对象或null,有一个定义的大小,通常等于int。

3) fn() 不是一个虚函数,因此对象中没有为 vtable 分配内存。

6赞 Doug T. 2/18/2009 #4

这:

class B
{
   public:
     int a;
     void fn();
};

就所有实际目的而言,等同于 C 代码:

struct B
{
   int a;
};

void fn(B* bInstance);

除 C++ 版本外,bInstance 将替换为 this 指针。这两个函数的内存都存在于堆栈上。因此,转换为结构等价物,您认为 sizeof(B) 是多少?

评论

0赞 Konrad Rudolph 2/19/2009
使函数参数更精确 - 也许将其放在自己的命名空间中。不过,这可能会分散你的注意力。;-)const
0赞 Zan Lynx 7/12/2013
该参数不是因为它没有被声明为constvoid fn() const;