C++ 类对象内存映射

2023-11-22

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

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

A * a = new A;

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很简单,因为它是非虚拟的。 (有时对于虚拟调用,如果对象的动态类型已知,则可以避免虚拟调度,就像这里一样。)


一个更长的例子要么会让你了解虚拟函数是如何工作的,要么会让你感到非常困惑:

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__其中,值会略有不同(它们是由编译器为当前函数名称生成的)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 类对象内存映射 的相关文章

随机推荐

  • Azure Pipelines 本地代理无法连接并出现 SSL 错误

    我们有一台本地服务器 Windows Server 2012 R2 其上运行着 Azure Pipelines 代理 今天 2022 年 1 月 31 日 该代理无法再连接到我们的 Azure DevOps 组织 从日志文件来看 我认为这是
  • 使用多索引绘制 matplotlib 表

    是否可以使用 matplotlib 绘制具有多索引的表格 就像 pandas 显示表格一样 我在网上找到最多的是这个打开 2012 年的 git 问题 给出以下示例数据框 arrays bar bar baz baz foo foo qux
  • 将 ObservableCollection 项绑定到 WrapPanel 中的 UserControl?

    我可能只是在这里遗漏了一些明显的东西 所以如果这是一个非常愚蠢的问题 我深表歉意 我的视图中有一个 WrapPanel 我需要将其绑定到 ViewModel 上的 ObservableCollection 此 ObservableColle
  • 通过 Javascript 将 DOMTimeStamp 转换为本地化的 HH:MM:SS MM-DD-YY

    The W3C 地理定位 API 除其他外 用途DOM时间戳其修复时间 这是 自 Unix 纪元开始以来的毫秒数 将其转换为人类可读格式并调整本地时区的最简单方法是什么 的一个版本Date构造函数将 自 Unix 纪元开始以来的毫秒数 作为
  • 捕获 HTTP 请求

    有没有办法使用 C 监视和捕获来自计算机的所有传出 HTTP 请求 我需要一种独立于浏览器的方式来记录访问过的 URL 我用小提琴手 http www fiddler2 com
  • Eclipse 中的代码颜色样式

    一个很好的简单问题 是否有类似的东西http studiostyl es 对于日食 Update 因为我使用此链接来了解如何使用该插件 所以我想我应该将其放在这里 http www eclipsecolorthemes org view p
  • 在接口类中声明抽象信号

    当实现类已经从 QObject QWidget 派生时 如何在抽象类 接口中声明 Qt 信号 class IEmitSomething public this should be the signal known to others vir
  • 在 Symfony2 + Twig 中使用变量进行翻译是可能的吗?

    第一个输出未翻译的字符串 chart name short trans charts 这个有效 与chart name short 应该输出 charts region area short trans charts 我错过了什么吗 似乎在
  • 从 Appengine 连接到 Google Containers 的 Kubernetes 服务

    我有一个包含 Appengine 部分和 Google 容器集群的项目 Appengine 应用程序需要对部署到 Google 容器的服务进行 http 调用 我知道我可以为服务分配一个外部 IP 将其硬编码到我的 Appengine 应用
  • 如何从 Play 2 Java 上的路由反向生成绝对 URL?

    我想从 Play 2 Java 中的控制器获取绝对 URL 我找到了Scala 的完全相同的问题 但我无法让它在 Java 中工作 public class MyController extends Controller public st
  • iOS:旋转 uiimageview

    在我的应用程序中 我有一个图像视图 它的名称是箭头 我以这种方式将其旋转 180 度 arrow transform CGAffineTransformMakeRotation M PI 它工作正常 但现在我希望这个图像视图返回到原始位置
  • 使用 jQuery 将 Div 位置设置为鼠标位置

    我试图将我的 Div 放置在用户点击我的图像的任何位置 test是我的 Div 并且myimg是我的形象 这是我的JS
  • 如何从 Javascript 调用原生 Iphone/Android 函数?

    我在 iPhone 和 Android 中都使用 Web 视图 在Android中 我使用创建一个变量调用原生 Android 函数 方法 但我没能在 iPhone 中找到类似的东西 那么 如何从 JavaScript 调用本机 Iphon
  • PLSQL从XML读取值?

    我有一个带有 XML 代码的字符串 我想在 PL SQL 中将它的值提取到变量中 XML 非常简单 与此没有什么不同
  • ReactJS 如何设置默认选中复选框?

    在分配默认值后 我无法更新复选框状态checked checked 在反应中 var rCheck React createElement input type checkbox checked checked value true Che
  • javax.naming.NameNotFoundException:名称 jdbc 未在此上下文中绑定

    我正在从事网络服务 并且是初学者 我尝试在服务文件中获取 Oracle Db 连接 但收到以下错误 javax naming NameNotFoundException Name jdbc is not bound in this Cont
  • 使用 ant 构建 Android 测试时如何使用 emma 过滤器?

    我知道在构建 Android 测试项目时如何在 ant 中使用 emma 但在使用 SDK 时找不到任何有关如何使用过滤器的提示 emma 网站在自己调用 emma 时对此进行了解释 但在 Android SDK 构建文件中 emma 并未
  • 强制浏览器获取asp.net应用程序中最新的js和css文件

    有些浏览器会缓存 js 和 css 文件 除非您强制刷新 否则无法刷新它们 最简单的方法是什么 我刚刚实施了这个似乎有效的解决方案 在页面上声明版本变量 public string version get set 从 web config
  • C++ - 为什么我要在堆上创建这些小部件?

    使用 C 和 Qt 创建 GUI 时 您可以创建一个标签 如下所示 QLabel label new QLabel Hey you centralWidgetParent 这会在堆上创建对象 并将一直保留在那里 直到我手动删除它或父对象被销
  • C++ 类对象内存映射

    当我们创建一个类的对象时 它的内存映射是什么样的 我更感兴趣的是对象如何调用非虚拟成员函数 编译器是否创建一个像 vtable 这样在所有对象之间共享的表 class A public void f0 int int in b1 A a n