C++ 虚拟继承内存布局

2024-01-16

虚拟继承内存布局

我试图完全理解虚拟继承和 vTables/vPtrs 的内存幕后发生的事情以及不发生的事情。

我有两个我编写的代码示例,我确切地理解它们工作的原因,但我只是想确保我心中对对象内存布局有正确的想法。

Here http://postimg.org/image/eyhxhc7g1/full/是图片中的两个示例,我只是想知道我对所涉及的内存布局的想法是否正确。

示例1:

class Top { public: int a;  };
class Left : public virtual Top {  public: int b; };
class Right : public virtual Top { public: int c; };
class Bottom : public Left, public Right { public:  int d; };

示例2:

与上面相同,但具有:

class Right : public virtual Top {
public:
    int c;
    int a;  // <======= added this
};

C++ 标准没有对对象布局做太多说明。虚拟函数表(vtable)和虚拟基指针甚至不是标准的一部分。所以问题和答案只能说明可能的实现。

快速查看您的绘图似乎显示了正确的布局。

您可能对这些进一步的参考资料感兴趣:

  • 多重继承被认为是有用的 http://www.drdobbs.com/cpp/multiple-inheritance-considered-useful/184402074一篇关于多重继承和虚拟继承情况下的布局的 ddj 文章。

  • 微软专利 http://www.google.com.pa/patents/US5754862描述 vfptr(虚拟函数表,又名 vtable)和 vbptr(虚拟基指针)的使用。

编辑:Bottom 是否继承Right::a or Left::a ?

In your test 2, Right and Left拥有同一个共同的父母Top。所以只有一个子对象Top within Bottom,因此,只有一个且相同的Top::a.

有趣的是,您在测试 2 中引入了一名成员a in Right。这是一a这与a继承自Top。它是一个独特的成员,只是“巧合”地与另一个成员同名。所以如果你访问a通过Right, Right::a隐藏Top::a(顺便说一下,这也是Bottom::Top::a, the Right::Top::a, the Left::Top::a)。在本例中,bottom.a 表示 Right::a,不是因为对象布局,而是因为名称查找(和隐藏)规则。这与实现无关:它是标准的且可移植的。

这里有一个测试 2 的变体来演示这种情况:

int main() {
    Bottom bottom; 
    bottom.a = 7; 
    cout << bottom.Top::a << endl << bottom.Left::Top::a << endl;
    cout << bottom.Right::Top::a << endl << bottom.Left::a << endl;
    cout << bottom.Right::a << endl <<endl;
    bottom.Right::a = 4; 
    bottom.Left::a = 3; 
    cout << bottom.Top::a << endl << bottom.Left::Top::a << endl;
    cout << bottom.Right::Top::a << endl << bottom.Left::a << endl;
    cout << bottom.Right::a << endl <<endl;

    cout << "And the addresses are: " << endl; 
    cout << " Bottom:       " << (void*)&bottom << endl; 
    cout << " Top:          " << (void*)static_cast<Top*>(&bottom) << endl;
    cout << " Left:         " << (void*)static_cast<Left*>(&bottom) << endl;
    cout << " Right:        " << (void*)static_cast<Right*>(&bottom) << endl;
    cout << " Top::a:       " << (void*)&bottom.Top::a << endl;
    cout << " Left::Top::a: " << (void*)&bottom.Left::Top::a << endl;
    cout << " Right::Top::a:" << (void*)&bottom.Right::Top::a << endl;
    cout << " Left::a:      " << (void*)&bottom.Left::a << endl;
    cout << " Rigth::a:     " << (void*)&bottom.Right::a << endl;
}; 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 虚拟继承内存布局 的相关文章

  • 以相反的顺序迭代可变参数模板参数

    如果我手动反转传递给它的模板参数的顺序 以下代码将起作用 template
  • 扫描文本文件时如何跳过行?

    我想扫描一个文件并在阅读之前跳过一行文本 我试过 fscanf pointer n struct test i j 但这个语法只是从第一行开始 我可以使用 scanf 使用以下指令跳过行 fscanf config file n n 格式字
  • 必须打开存储才能执行此操作 - System.IO.Packaging.Package

    我正在使用 System IO Packaing Package 类来压缩文件 我的应用程序的多个实例可以同时运行 并读取和保存文件 当处理小文件时 一切似乎都很好 但是当涉及大文件时 如果应用程序的两个实例同时保存 我会收到一个异常 消息
  • SetWindowsHookEx 函数返回 NULL

    我正在研究 DLL 注入 但收到错误如下 挂接进程失败 87 参数不正确 目标进程和dll都是64位的 注入代码为 BOOL HookInjection TCHAR target TCHAR dll name https msdn micr
  • 检查列表是否包含另一个列表。 C#

    编辑 只是说 ContainsAllItem 中的注释解释得最好 很抱歉问这个问题 我知道以前有人问过这个问题 但我只是不明白 好的 所以我想检查一个列表是否包含另一个列表中的所有项目WITHOUT重叠 以及根据类字符串 名称变量 称为项目
  • Android NDK C++“wstring”支持

    我有用 C 编写的源代码 lib 现在我想在 Android NDK 项目 NDK 6 中编译并使用相同的源代码 lib 我能够编译大多数 C 文件 除了基于 std wstring 的功能 在 Application mk 中 当我指定时
  • 在 GCC 和 Clang 下,使用 lambda 的简单 RAII 包装器的复制初始化意外失败

    我在创建一个简单的 RAII 包装器时遇到了一个意想不到的问题 更不用说下面代码的逻辑不完整性了 复制构造函数和赋值运算符未删除等 这意味着是一个SSCCE 令我印象深刻的是复制初始化我的包装器与临时 lambda 的结果会导致编译错误 而
  • rand() 播种与 time() 问题

    我很难弄清楚如何使用 rand 并使用 Xcode 用 time 为其播种 我想生成 0 到 1 之间的随机十进制数 该代码为我提供了元素 1 和 2 看似随机的数字 但元素 0 始终在 0 077 左右 有什么想法吗 我的代码是 incl
  • F10键没被抓住

    I have a Windows Form and there overriden ProcessCmdKey However this works with all of the F Keys except for F10 I am tr
  • 将成员函数作为参数传递/c++

    我想用 C 实现一个类b可以通过封装该迭代器类型的成员集进行某种迭代 喜欢 b object for each x do function f so 函数 f会得到每个人的x成员并做任何事情 比方说 void function f x me
  • .net Framework (.net 4.0) 中定义 Base 3 数字的类

    我正在寻找一些可以用来定义 3 基数 三进制数 的类 有什么我可以在 net 框架中使用的东西或者我需要写一些东西吗 谢谢你的帮助 您可以使用解析Convert ToInt32 s base http msdn microsoft com
  • 指示泛型返回动态类型的对象

    这个问题是我原来问题的后续问题here https stackoverflow com questions 2541184 using a type object to create a generic 假设我有以下泛型类 简化 class
  • QThread - 使用槽 quit() 退出线程

    我想在线程完成运行时通知对象 但是 我无法让线程正确退出 我有以下代码 处理器 cpp thread new QThread tw new ThreadWorker connect tw SIGNAL updateStatus QStrin
  • 如何将字符串转换为 Indian Money 格式?

    我正在尝试将字符串转换为印度货币格式 例如如果输入为 1234567 则输出应为 12 34 567 我编写了以下代码 但它没有给出预期的输出 CultureInfo hindi new CultureInfo hi IN string t
  • 如何在 VS Code 中为 CMake 项目设置 C/C++ IntelliSense?

    我正在尝试使用 libTooling 编写一个工具 我对其进行了设置 以便它可以使用 LLVM 文档中的示例进行编译 然而 C C IntelliSense 似乎不适用于 CMake 项目 我的工具位于
  • C++ 标准中短语“构造函数没有名称”的含义

    在尝试理解 C 标准中的 构造函数没有名称 这句话时 我似乎在 clang 中发现了一个错误 有人可以证实这一点吗 VS2015 and gcc rejects this code and I think they it are is co
  • 微软语音识别速度

    我正在使用微软的语音识别器开发一个小型练习应用程序 对于我正在做的事情来说 我似乎无法让它足够快地识别单个单词 我希望能够正常说话 系统将从我所说的内容中抓取 关键字 并生成一个字符串 目前我正在使用 5 个单词的自定义语法 红 蓝 黄 绿
  • 是否有任何不使用公共虚拟方法的正当理由? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 是否有任何不使用公共虚拟方法的正当理由 我在某处读到我们应该避免使用公共虚拟方法 但我想向专家确认这是否是有效的声明 对于良好且稳定的 API
  • 通过 cmake 链接作为外部项目包含的 opencv 库[重复]

    这个问题在这里已经有答案了 我对 cmake 比较陌生 经过几天的努力无法弄清楚以下事情 我有一个依赖于 opencv 的项目 它本身就是一个 cmake 项目 我想静态链接 opencv 库 我正在做的是我的项目中有一份 opencv 源
  • 将文本从文本文件添加到 PDF 文件[重复]

    这个问题在这里已经有答案了 这是我的代码 using FileStream msReport new FileStream pdfPath FileMode Create step 1 using Document pdfDoc new D

随机推荐

  • Xcode UI 测试 - 使用 addSubview 添加的 Uiview 对于 UI 测试完全不可见

    我一直在尝试 XCode 7 3 上的新 UI 测试 并且发现了对我来说似乎是一个错误 问题是通过 添加的视图 添加子视图 方法对于UI测试系统来说似乎是完全不可见的 我有这样的看法 这个 UIview 创建代码 let container
  • 如何使用 *ngFor 迭代对象键?

    我一直在挖掘 发现我可以使用以下方法在对象上使用 ngFor div div where ObjNgFor管道是 Pipe name ObjNgFor pure false export class ObjNgFor implements
  • XHTML:将 DIV 放置在 A 标记中

    Is it alright将 div 标签放置在锚标签内 div 的内容会将页面重定向到锚标记的 href 吗 将 div 标签放在锚标签内可以吗 Yes if 您正在使用 HTML5 XHTML5 和 锚标记不在内联上下文中 即仅允许短语
  • 如何使用php从url读取xml文件

    我必须从 URL 读取 XML 文件 map url http maps google com maps api directions xml origin merchant address url destination customer
  • 从 PHP 中的函数返回多个值 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我有这个函数 在调用它时返回三个值
  • Union 赋值中的不兼容类型

    Mypy 向我打印以下消息 x py 74 错误 赋值中的类型不兼容 表达式具有类型 Union str Dict str str 变量的类型为 str 是不是很奇怪 str是其一部分Union str Dict str str 代码如下
  • 从 PHP CLI 打开 Vim

    当你从提交命令中删除 m 时 如何从像 svn 和 git 那样的 CLI 打开 vim 我收到以下错误 Vim 警告 输出不是到终端 echo Please edit this file gt file name vim file nam
  • 如何使用 Perl 截取网页屏幕截图?

    是否可以用 Perl 编写一个脚本来打开不同的 URL 并保存每个 URL 的屏幕截图 你可以使用WWW 机械化 Firefox http search cpan org perldoc WWW Mechanize Firefox控制 Fi
  • 使用 FluentNHibernate 映射通用 EntityBase

    我的所有实体类型都有一个基类 就像 public abstract class EntityBase
  • 有谁知道这个Android类的功能吗? “com.google.apps.tiktok.tracing.db”?

    我正在使用 Android Studio Logcat 调试我自己的应用程序 并遇到一些涉及 com google apps tiktok tracing db 类的日志 这和抖音有关系吗 我从未在手机上安装过该应用程序 我的 Logcat
  • 压缩图像的最佳方法 Javascript React Web App

    我正在寻找最佳的解决方案来压缩我收到并需要存储在数据库中的图像 实际上 我将图像转换为base64 然后将其发送到服务器 handleImage e gt e preventDefault let reader new FileReader
  • 带有准备好的语句的 PostgreSQL 内部查询

    我有一个表来存储联系人 我想获取添加 user id 为 some number 的列的最大值 并将其设置为当前插入记录的相同列值 我正在使用准备好的语句 pg prepare db add INSERT INTO CONTACTS c u
  • 重置 FactoryGirl 测试的“序列”

    有谁知道如何重置FactoryGirl的序列方法 我有一个创建任务列表的工厂 我希望每次都从 1 开始 我使用 序列 是因为任务列表是一个关联模型 所以每次使用时我都需要增加顺序FactoryGirl create直到我调用重置 你需要写F
  • 在 Javascript 中检测 MS Surface 虚拟键盘

    有没有办法通过 Javascript 检测 MS Surface 的虚拟键盘何时显示在网页中 虚拟键盘覆盖了页面上的活动文本字段 我需要能够检测到这一点 以便我可以重新布局页面以更好地使用剩余的窗口区域 None
  • 仅通过单击节点图像来展开/折叠 TreeView

    我的表单上有一个包含大量项目 节点的 TreeView 当我双击节点的项目时 我运行一个过程 取决于单击的项目 我的问题是 我希望它仅在单击节点的图标 或 号 时展开 折叠 如果我双击一个项目则不会 类似的问题 http www delph
  • Ant构建执行cordova

    我为我的 cordova 项目创建了一个 ant 构建 如下所示
  • 如何使用 datafactory 管道转换 xml 数据

    我们如何将 XML 负载中的数据保存到 Blob 存储中 input
  • 对于 Jenkins git 插件,建议在哪里运行 git config ?

    在詹金斯的领导下我也有同样的情况longpaths中描述的问题这个线程 https stackoverflow com questions 22575662 filename too long in git for windows This
  • R Markdown 版本的 \framesubtitle?

    以下是我所知道的创建带有字幕的投影仪幻灯片的最少 TeXy 方法 output beamer presentation Title of Slide framesubtitle Subtitle of Slide Frame content
  • C++ 虚拟继承内存布局

    虚拟继承内存布局 我试图完全理解虚拟继承和 vTables vPtrs 的内存幕后发生的事情以及不发生的事情 我有两个我编写的代码示例 我确切地理解它们工作的原因 但我只是想确保我心中对对象内存布局有正确的想法 Here http post