C++ 多重继承转换如何工作?

2023-12-15

这个问题帮助我理解了一些,但我的问题与他们的略有不同。

据我了解,C++ 中的基本类型转换涉及将内存中的结构重新解释为不同的结构。例如:

class Building{int sqFootage;};

class Office : public Building{int cubicles;};

int main(int argc, char** argv){
    Office *foo = new Office();
    /*The cubicles member appears after the sqFootage member on an Office,
    * so the foo pointer is really just a Building* with some extra
    * information after it.
    */
    Building *bar = (Building*)foo;
    return 0;
};

这里的关键点是,办公室在内存中可以被解释为建筑物,而无需对结构进行任何改变。这在多重继承的情况下会崩溃:

class Animal{bool alive;};

class WaterDweller : public Animal{float swimSpeed;};

class LandDweller : public Animal{float runSpeed;};

class Amphibian : public WaterDweller, public LandDweller{float transitionSpeed};

int main(int argc, char** argv){
    Amphibian *amph = new Amphibian();
    LandDweller *land = (LandDweller*)amph;
    WaterDweller *sea = (WaterDweller*)amph;
}

无法解释amph作为两个LandDweller and a WaterDweller无需重组Amphibian内存中的结构。假设这些转换有任何有用的意义,它们是如何工作的?如果没有的话,会static_cast, dynamic_cast, or reinterpret_cast这里合适吗?

编辑:非常感谢您的回答 Sneftel。这小博士链接您在其中一条评论中提供的内容非常有帮助,并且我会牢记避免 c 风格强制转换的建议。

对于那些好奇的人,以下是我尝试运行此代码时得到的指示:

land 0x22c8018
sea 0x22c8010
run 0x22c801c
swim 0x22c8014
land alive 0x22c8018
sea alive 0x22c8010

您可以在这里看到,即使陆地居民和水居民继承自同一基类,它们也包含自己的副本,就好像基类不同一样。这就导致了斯尼夫特尔在评论中提到的钻石问题。


如果你查看存储在的地址land,你会注意到它的数字比amph。这是因为,在 C++ 中,强制转换最终可能会将指针算术作为其内部操作的一部分。Amphibian has a WaterDweller其中,还有一个LandDweller在那之后。当转换为数据不是从派生类开头开始的基类型时,指针将调整到该基类数据开始的位置。

顺便说一句,请采纳 Dieter 的建议,不要在 C++ 中使用 C 风格的强制转换(特别是对于指针类型)。 C++ 中 C 风格强制转换的行为是以下内容的大杂烩static_cast, reinterpret_cast, and const_cast,并且很容易最终做出与您预期不同的事情,甚至没有编译器警告。最好让你正在做的演员类型变得明确。

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

C++ 多重继承转换如何工作? 的相关文章

  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • 没有强命名的代码签名是否会让您的应用程序容易被滥用?

    尝试了解authenticode代码签名和强命名 我是否正确地认为 如果我对引用一些 dll 非强命名 的 exe 进行代码签名 恶意用户就可以替换我的 DLL 并以看似由我签名但正在运行的方式分发应用程序他们的代码 假设这是真的 那么您似
  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定
  • Python 类继承 - 诡异的动作

    我观察到类继承有一个奇怪的效果 对于我正在处理的项目 我正在创建一个类来充当另一个模块的类的包装器 我正在使用第 3 方 aeidon 模块 用于操作字幕文件 但问题可能不太具体 以下是您通常如何使用该模块 project aeidon P
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co

随机推荐