为什么 C++ 需要公共继承,忽略友元声明,才能使动态向下转型工作?

2024-02-13

我们在这里上课B,从类继承A,并且它有一个friend class C。作为朋友,C应该可以访问所有内容B, 包括A基类。

为了测试它,

  1. 首先我们创建一个B实例。
  2. 我们将其地址升级为A*
  3. 然后我们尝试用dynamic_cast<>再次到B*.

预期结果是取回原来的地址B实例。

#include <cstdint>
#include <cstdio>

class A {
  public:
    virtual ~A() {};
};

class C;

class B : protected A { // <- this should be public to work! Why?
  friend C;
};

class C {
  public:
    void doit() {
      B *b = new B();
      printf("b= %p\n", b);
      A *a = static_cast<A*>(b);
      printf("a= %p\n", a);
      B *bb = dynamic_cast<B*>(a);
      printf("bb=%p\n", bb);
      delete b;
    };
};

int main() {
  C c;
  c.doit();
  return 0;
};

类似情况下的常见问题,即基类必须是多态的(这里由其空虚拟析构函数保证),在这里得到了解决。

然而,动态转换仍然不起作用:bb应该有相同的地址b.

我的实验表明,使其发挥作用的唯一方法是A is a public的基类B。但...C是...的朋友B. 它甚至不起作用protected.

为什么会这样呢?

如果重要的话,我使用 gcc-8。


将“dynamic_cast”视为全局函数。 “朋友C;”将友谊给予“class C”而不是“dynamic_cast”。

成员访问检查是在编译时进行的。

Dynamic_cast 在运行时检查基本可访问性。 RTTI 具有基本可访问性信息(请参阅 MS 实现 rtti.cpp;__RTDynamicCast),但没有友谊。

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

为什么 C++ 需要公共继承,忽略友元声明,才能使动态向下转型工作? 的相关文章

随机推荐

  • PHP 警告:DOMDocument::loadHTML():属性 alt 重新定义

    我在 CentOS 上运行以下代码 roster utils gt getContentCURL http exporter nih gov ExPORTER Catalog aspx docmp new DOMDocument docmp
  • 如何在没有DLL的情况下编译SDL程序并运行它

    是否可以将SDL库程序编译为exec并在没有 sdl dll 的情况下运行它 例如 假设我编写了 sdl 程序 它可以工作 但问题是要在 Windows 上运行该程序 我需要在同一文件夹或系统文件夹中包含 sdl dll 是否可以编译它 以
  • Spring基于注解的DI vs xml配置?

    最近 在我们的团队中 我们开始讨论在代码中使用 spring 注释来定义 spring 依赖项 目前我们正在使用 context xml 来定义我们的依赖项 您能给我一些关于这两种方法的线索吗 什么时候使用一种方法更好 编辑 我知道这对于一
  • 具有综合和继承属性的深度递归 qi 语法(解析器)

    我使用spirit qi 语法来构造并返回非平凡对象作为其合成属性 问题是我希望语法递归地相互依赖 使用递归很简单rules 但我想要递归grammars 这是一些示例代码 请注意 循环引用 的注释 显然 如果我取消注释这些行 则无法编译
  • PhoneGap 在表单提交时将图像上传到服务器

    我在这里面临问题 因为一旦您选择图片 phonegap 图像就会上传到服务器 我不想在提交表单之前上传图像 图像自动上传到服务器 这是我不想要的 我想使用表单上传图像 其中表单包含更多与图像一起发送所需的字段 可以通过哪些方式提交表单
  • 如何让Vue在shadow dom中工作

    我有一个 Shadow dom 其中包含根元素和一个 vue 组件
  • 创建一个服务来在 Android 应用程序中的所有活动之间共享数据库连接?

    我一直在试图找出在我的 Android 应用程序中处理本地数据库访问的最佳方法 我一直在每个活动中创建一个数据库连接对象 但这似乎是一种非常低效的做事方式 做了一些研究我偶然发现这次讨论 http groups google com gro
  • 连接四游戏检查胜利 JS

    我正在开发我的第一个完整程序 并进行了两周的编程 但遇到了我似乎无法弄清楚的障碍 我正在制作一个 connect 4 游戏 并首先在 JavaScript 中构建逻辑 然后再推送到 DOM 我开始使用构造函数创建的单元对象来制作它 然后将其
  • 实现 SMS 的 GSM 调制解调器 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个为大约 1000 位用户提供服务的网站 负责协调活动安排 我想让我们的系统能够向用户发送短信 我
  • 在 python 中将 pcolormesh 与 3 个一维数组一起使用

    我正在尝试使用 pcolormesh 绘制 3 个填充坐标和值的一维数组 下面的数组只是示例 但它们遵循相同的原则 我有 3 个数组 一个用于 x 坐标 一个用于 y 坐标 一个用于它们的值 或 z 每个索引对应一个位置 索引 0 对应于
  • R 数据表中最近的“n”滚动连接

    With data table 我们可以使用以下方法将一个数据集中的值与另一个数据集中最接近的值连接起来roll nearest 一些示例数据 dt1 lt data table x c 15 101 id1 c x y dt2 lt da
  • 将行保存为 csv 格式

    我想将数据库中的一组行保存到 csv 文件中 考虑到数据是 ascii 字符 没有任何奇怪的字符 以下内容就足够了吗 my csv row join row save csv row to file 我担心的是 这是否会创建任何工具都可以接
  • 错误“mat-dialog-content”不是已知元素

    我正在尝试使用角度材料创建登录表单 我在用 angular material 7 3 0 In app module ts我导入了以下内容并将它们也放入了导入数组中 import MatToolbarModule MatFormFieldM
  • NHibernate:保留一个带有子对象的对象

    我正在尝试保留一个带有子对象集合的对象 我不能先坚持孩子 因为有FK关系 我可以先保存父级 然后将子级添加到其中 但这会带来更多工作 基本上 我只是想一步一步保存一个完全填充的对象 而不是将其分成几部分 我的映射有问题吗 抱歉它看起来很丑
  • 如何将 mailerlite.com 注册表单与 React 集成?

    Mailerlite com 允许您在网站中嵌入电子邮件注册表单 如何将其与 React 集成 具体来说 如何集成JavaScript代码 下面是一个将 HTML 表单转换为 React 代码的示例 将所有出现的 CODE 替换为示例表单中
  • 从 BouncyCastle X509 证书获取私钥? C#

    通常当我抓住一个X509Certificate2我可以从我的密钥库中调用 PrivateKey检索证书的私钥作为AsymmetricAlgorithm 但是我决定使用 Bouncy Castle 及其实例X509Certificate只有一
  • 如何在input标签内显示div?

    我正在尝试为我的网站创建像 stackoverflow 这样的标签 我网站上的用户将创建用于过滤结果或许多其他操作 如搜索 专业知识等 的标签 我能够创建标签 但无法像我们在 stackoverflow 中那样在输入框中显示它 标签之间的边
  • 为什么“out of source”构建不是默认的?

    我最近发现 您可以配置 Visual Studio 但这个问题对于任何编译器都是一样的 将中间 o 文件转储到源代码树之外的单独文件夹中 而不是与每个单独的项目并置 这使得清理项目 归档到 zip 或类似的东西变得很容易 为什么这种配置不常
  • Asp.Net AJAX 中嵌套 UpdatePanel 中的 AsyncPostback 之间存在差异

    在 ASP net AJAX 项目 WebForms 中 我有一个 UpdatePanel 在 UpdatePanel 中我有多个带有 UpdatePanel 的嵌套控件 基本上我有控件树 家长控制是网站的重要组成部分 我无法触摸它 而且它
  • 为什么 C++ 需要公共继承,忽略友元声明,才能使动态向下转型工作?

    我们在这里上课B 从类继承A 并且它有一个friend class C 作为朋友 C应该可以访问所有内容B 包括A基类 为了测试它 首先我们创建一个B实例 我们将其地址升级为A 然后我们尝试用dynamic cast lt gt 再次到B