C ++类对象内存映射 [英] C++ class object memory map

查看:141
本文介绍了C ++类对象内存映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我们创建一个类的对象时,它的内存映射是什么样子。我更感兴趣的是该对象如何调用非虚拟成员函数。编译器是否创建一个像所有对象之间共享的表vtable?

When we create an object of a class what does it memory map look like. I am more interested in how the object calls the non virtual member functions. Does the compiler create a table like vtable which is shared between all objects?

class A
{
public:
  void f0() {}
  int int_in_b1;
};

A * a = new A;

a的内存映射是什么?

What will be the memory map of a?

推荐答案

您可以想象这段代码:

struct A {
  void f() {}
  int int_in_b1;
};

int main() {
  A a;
  a.f();
  return 0;
}

转换成类似的东西:

struct A {
  int int_in_b1;
};
void A__f(A* const this) {}

int main() {
  A a;
  A__f(&a);
  return 0;
}

调用是直接的,因为它是非-虚拟。 (有时对于虚拟调用,如果已知对象的动态类型,则可以避免虚拟分派,如在此处所述。)

Calling f is straight-forward because it's non-virtual. (And sometimes for virtual calls, the virtual dispatch can be avoided if the dynamic type of the object is known, as it is here.)

一个更长的例子,将给你一个关于虚函数如何工作或混淆你的想法:

A longer example that will either give you an idea about how virtual functions work or terribly confuse you:

struct B {
  virtual void foo() { puts(__func__); }
};
struct D : B {
  virtual void foo() { puts(__func__); }
};

int main() {
  B* a[] = { new B(), new D() };
  a[0]->foo();
  a[1]->foo();
  return 0;
}

成为:

void B_foo(void) { puts(__func__); }
void D_foo(void) { puts(__func__); }

struct B_VT {
  void (*foo)(void);
}
B_vtable = { B_foo },
D_vtable = { D_foo };

typedef struct B {
  struct B_VT* vt;
} B;
B* new_B(void) {
  B* p = malloc(sizeof(B));
  p->vt = &B_vtable;
  return p;
}

typedef struct D {
  struct B_VT* vt;
} D;
D* new_D(void) {
  D* p = malloc(sizeof(D));
  p->vt = &D_vtable;
  return p;
}

int main() {
  B* a[] = {new_B(), new_D()};
  a[0]->vt->foo();
  a[1]->vt->foo();
  return 0;
}

每个对象只有一个vtable指针,您可以添加许多虚拟方法该类不影响对象大小。 (vtable增长,但这是每个类存储一次,并且不是显着的大小开销。)请注意,我已经简化了这个例子中的许多细节,但它做工作:析构函数没有被解决(这里应该另外虚拟),它泄漏内存,并且__ func __ 值将略有不同(它们由编译器为当前函数名),等等。

Each object only has one vtable pointer, and you can add many virtual methods to the class without affecting object size. (The vtable grows, but this is stored once per class and is not significant size overhead.) Note that I've simplified many details in this example, but it does work: destructors are not addressed (which should additionally be virtual here), it leaks memory, and the __func__ values will be slightly different (they're generated by the compiler for the current function's name), among others.

这篇关于C ++类对象内存映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆