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

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

B* pb = new B;

fn() 的内存在哪里?

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

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

4

4 回答 4

15

fn() 的内存在哪里?

因为它是一个正常的功能,在你程序的代码部分的某个地方。该位置对于类的所有实例都是相同的。B实际上,它与via的实例化无关pb

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

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

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

于 2009-02-18T14:50:41.210 回答
6

这:

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

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

struct B
{
   int a;
};

void fn(B* bInstance);

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

于 2009-02-18T15:04:38.883 回答
2

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

于 2009-02-18T14:49:13.520 回答
1

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

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

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

于 2009-02-18T14:53:48.613 回答