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

时间:2009-02-18 14:47:13

标签: c++ sizeof

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

如果我使用

创建B的对象
B* pb = new B;

fn()的内存位于何处?

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

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

4 个答案:

答案 0 :(得分:15)

  

fn()的内存位于何处?

因为它是一个普通的函数,所以在程序的代码部分的某个地方。对于该类的所有实例,此位置相同。实际上,它与通过B pb的实例化无关。

  

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

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

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

答案 1 :(得分:6)

此:

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

出于所有实际目的,等同于C代码:

struct B
{
   int a;
};

void fn(B* bInstance);

除了在C ++版本中,bInstance被替换为this指针。两个函数的内存都存在于堆栈中。所以转换为struct equivelant,你认为(B)的大小是什么?

答案 2 :(得分:2)

只有一个指针存储为虚函数(在vtable中),而不是非虚函数。

答案 3 :(得分:1)

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

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

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