继承和多态性的低级细节

2024-03-14

这个问题是我心中的一大疑惑,也很难用语言来形容。有时它看起来很明显,有时却很难破解。所以问题是这样的::



class Base{
public:
     int a_number;

     Base(){}
     virtual void function1() {}
     virtual void function2() {}
     void function3() {}
};

class Derived:public Base{
public:
     Derived():Base() {}
     void function1() {cout << "Derived from Base" << endl; 
     virtual void function4() {cout << "Only in derived" << endl;}
};

int main(){

      Derived *der_ptr = new Derived();
      Base *b_ptr = der_ptr;  // As just address is being passed , b_ptr points to derived                object

      b_ptr -> function4(); // Will Give Compilation ERROR!!

      b_ptr -> function1(); // Calls the Derived class overridden method

      return 0;

}
  

Q1.虽然 b_ptr 指向 Derived 对象,但它访问哪个 VTABLE 以及如何访问?因为 b_ptr -> function4() 给出编译错误。或者 b_ptr 只能访问派生 VTABLE 中基类 VTABLE 的大小?

Q2。既然 Derived 的内存布局一定是 (Base,Derived) ,那么 Base 类的 VTABLE 是否也包含在 Derived 类的内存布局中呢?

Q3。既然基类Vtable的function1和function2指向Base类的实现,而派生类的function2指向Base类的function2,那么基类中真的需要VTABLE吗? (这可能是我能问的最愚蠢的问题,但在我目前的状态下我仍然对此表示怀疑,答案必须与问题1的答案相关:))

请给出意见。

感谢您的耐心等待。


作为进一步的说明,这里是 C++ 程序的 C 版本,显示了 vtable 等。

#include <stdlib.h>
#include <stdio.h>

typedef struct Base Base;
struct Base_vtable_layout{
    void (*function1)(Base*);
    void (*function2)(Base*);
};

struct Base{
    struct Base_vtable_layout* vtable_ptr;
    int a_number;
};

void Base_function1(Base* this){}

void Base_function2(Base* this){}

void Base_function3(Base* this){}

struct Base_vtable_layout Base_vtable = {
    &Base_function1,
    &Base_function2
};

void Base_Base(Base* this){
    this->vtable_ptr = &Base_vtable;
};

Base* new_Base(){
    Base *res = (Base*)malloc(sizeof(Base));
    Base_Base(res);
    return res;
}

typedef struct Derived Derived;
struct Derived_vtable_layout{
    struct Base_vtable_layout base;
    void (*function4)(Derived*);
};

struct Derived{
    struct Base base;
};

void Derived_function1(Base* _this){
    Derived *this = (Derived*)_this;
    printf("Derived from Base\n");
}

void Derived_function4(Derived* this){
    printf("Only in derived\n");
}

struct Derived_vtable_layout Derived_vtable = 
{
    { &Derived_function1,
      &Base_function2},
    &Derived_function4
};

void Derived_Derived(Derived* this)
{
    Base_Base((Base*)this);
    this->base.vtable_ptr = (struct Base_vtable_layout*)&Derived_vtable;
}      

Derived* new_Derived(){
    Derived *res = (Derived*)malloc(sizeof(Derived));
    Derived_Derived(res);
    return res;
}



int main(){
      Derived *der_ptr = new_Derived();
      Base *b_ptr = &der_ptr->base;
      /* b_ptr->vtable_ptr->function4(b_ptr); Will Give Compilation ERROR!! */
      b_ptr->vtable_ptr->function1(b_ptr);
      return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

继承和多态性的低级细节 的相关文章

  • 为什么存在 async 关键字

    浏览 msdn 9 频道视频时 我发现以下未答复的评论 希望有人能解释一下 我不明白 async 关键字的意义 为什么不直接允许 任何时候方法返回任务时都会使用await关键字 就像迭代器一样 可以在任何返回 IEnumerable 的方法
  • 内联函数/方法

    声明 内联函数必须在调用之前定义 这个说法正确吗 EDIT 该问题最初是德语 内联功能穆森 弗 伊赫雷姆 奥夫鲁夫定义 sein 也许它对任何人都有帮助 是的 它是正确的 但只是部分正确 它可能正确地重新构建如下 内联函数必须在每个翻译单位
  • ASP.NET Core 与现有的 IoC 容器和环境?

    我想运行ASP NET 核心网络堆栈以及MVC在已托管现有应用程序的 Windows 服务环境中 以便为其提供前端 该应用程序使用 Autofac 来处理 DI 问题 这很好 因为它已经有一个扩展Microsoft Extensions D
  • 为什么大多数平台上没有“aligned_realloc”?

    MSVC有自己的非标准函数 aligned malloc aligned realloc and aligned free C 17和C11引入了 std aligned alloc 其结果可以是de分配有free or realloc B
  • CultureInfo 的实例(来自相同的文化)根据操作系统而变化

    我有一个网站 上面写着这样的日期 CultureInfo cultureInfo CultureInfo GetCultures CultureTypes AllCultures FirstOrDefault c gt string Equ
  • 在 C# Winforms 应用程序中嵌入 Windows XP 主题

    我有一个旧版 C Windows 窗体应用程序 其布局是根据 Windows XP 默认主题设计的 由于需要将其作为 Citrix 应用程序进行分发 该应用程序现在看起来像经典主题应用程序 因为 Citrix 不鼓励使用主题系统服务 所以
  • 选择列表逻辑应位于 ASP.NET MVC、视图、模型或控制器中的什么位置?

    我觉得我的问题与这个问题很接近 但我想对这样的代码应该放在哪里进行更一般的讨论 Asp Net MVC SelectList 重构问题 https stackoverflow com questions 2149855 asp net mv
  • SFINAE 如何使用省略号?

    过去 当使用 SFINAE 选择构造函数重载时 我通常使用以下内容 template
  • 如何使用MySqlCommand和prepare语句进行多行插入?(#C)

    Mysql 给出了如何使用准备语句和 NET 插入行的示例 http dev mysql com doc refman 5 5 en connector net programming prepared html http dev mysq
  • 获取尚未实例化的类的函数句柄

    我对 C 相当陌生 我想做的事情可能看起来很复杂 首先 我想获取一些函数的句柄以便稍后执行它们 我知道我可以通过以下方式实现这一目标 List
  • TcpClient 在异步读取期间断开连接

    我有几个关于完成 tcp 连接的问题 客户端使用 Tcp 连接到我的服务器 在接受客户端后listener BeginAcceptTcpClient ConnectionEstabilishedCallback null 我开始阅读netw
  • 如何在 C++ 中将 CString 转换为 double?

    我如何转换CString to a double在 C 中 Unicode 支持也很好 Thanks A CString可以转换为LPCTSTR 这基本上是一个const char const wchar t 在 Unicode 版本中 知
  • 两种类型的回发事件

    1 我发现了两篇文章 每篇文章对两种类型的回发事件的分类都略有不同 一位资源说两种类型的回发事件是Changed事件 其中控件实现 IPostbackDataHandler 当数据在回发之间更改时触发 然后Raised事件 其中控件实现 I
  • WPF。如何从另一个窗口隐藏/显示主窗口

    我有两个窗口 MainWindow 和 Login 显示登录的按钮位于主窗口 this Hide Login li new Login li Show 登录窗口上有一个检查密码的按钮 如果密码正确 我如何显示主窗口 将参数传递给 MainW
  • DataTable:通过 LINQ 或 LAMBDA 进行动态 Group By 表达式

    我有一个数据表 我想在其中对未指定数量的字段进行分组 发生这种情况的原因是用户可以选择他想要分组的字段 所以 实际上 我将选择推入列表中 在这个选择上 我必须对我的数据表进行分组 想象一下这段代码 VB 或 C 都一样 public voi
  • ASP.NET JQuery AJAX POST 返回数据,但在 401 响应内

    我的应用程序中有一个网页 需要调用我设置的 Web 服务来返回对象列表 这个调用是这样设置的 document ready function var response ajax type POST contentType applicati
  • 初始化 LPCTSTR /LPCWSTR [重复]

    这个问题在这里已经有答案了 我很难理解并使其正常工作 基本上归结为我无法成功初始化这种类型的变量 它需要有说的内容7 2E25DC9D 0 USB003 有人可以解释 展示这种类型的正确初始化和类似的值吗 我已查看此站点上的所有帮助 将项目
  • 从 Delphi 调用 C# dll

    我用单一方法编写了 Net 3 5 dll 由Delphi exe调用 不幸的是它不起作用 步骤 1 使用以下代码创建 C 3 5 dll public class MyDllClass public static int MyDllMet
  • 受限 AppDomain 中的代码访问安全异常

    Goal 我需要在权限非常有限的 AppDomain 中运行一些代码 它不应该访问任何花哨或不安全的内容 except对于我在其他地方定义的一些辅助方法 我做了什么 我正在创建一个具有所需基本权限的沙箱 AppDomain 并创建一个运行代
  • OSError: [WinError 193] %1 不是有效的 Win32 应用程序,同时使用 CTypes 在 python 中读取自定义 DLL

    我正在尝试编写用 python 封装 C 库的代码 我计划使用 CTypes 来完成此操作 并使用 Visual Studio 来编译我的 DLL 我从一个简单的函数开始 在 Visual Studio 内的标头中添加了以下内容 然后将其构

随机推荐

  • 使用 MinGW 为 Windows 构建 Cairo(链接 libpng 的问题)

    我正在尝试建立cairo http www cairographics org 在 Windows 上使用 MinGW 和 MSYS 我正在按照说明进行操作为 Windows 编译 GTK 2 16 4 http kemovitra blo
  • 应用内购买陷入“缺少元数据”状态

    我正在尝试设置应用内购买 但我不知道如何摆脱如下所示的 丢失元数据 我从页面上看到的唯一黄点是 本地化 部分 但我完成了 显示名称 和 描述 我不知道我还能做什么或者我做错了什么 在此处添加应用程序的任何类型的屏幕截图 然后保存并提交 它应
  • PHP 中保持登录状态或用户登录时记住我的代码是什么

    我不知道如何编写 php 代码保持登录状态或记住我当用户登录时检查选项 我想让用户保持登录状态至少 60 分钟 直到用户关闭浏览器 PHP 中的代码是什么 如果您正在使用session http www php net manual en
  • Safari 的媒体记录 API 替代方案

    我需要通过浏览器从相机录制视频 我已经使用媒体记录 API 为 Chrome 和 Firefox 完成了此操作 var options mimeType video webm codecs vp9 mediaRecorder new Med
  • 将我的日历应用程序与其他日历同步

    我希望我的日历应用程序与其他日历应用程序 雅虎日历 Google 日历 iCloud 日历 Microsoft Exchange 和 Microsoft Outlook 实时同步 有什么办法可以做到吗 我知道我们可以为谷歌日历做到这一点 但
  • 创建 C++ 枚举和依赖数据结构时如何避免重复? [复制]

    这个问题在这里已经有答案了 可能的重复 枚举到字符串 如果无效 未找到 则返回枚举整数值 https stackoverflow com questions 10175260 enum to string return the enum i
  • 如何对数组进行分组

    我正在尝试使用相同的标签对相似的对象进行分组 目前 这是我收到的 JSON const sizes id value 2496 label XS value 2499 label S type First Size id value 286
  • 如何通过后台服务在android中每天的特定时间重复通知

    您好 我正在开发应用程序 我通过后台服务设置了用户输入日期和时间的通知 现在我想设置每天下午 6 点的通知 闹钟 询问用户是否要添加另一个条目 我怎样才能实现这个目标 我应该使用相同的后台服务还是广播接收器 请给我更好的解决方案 教程将是个
  • 如何在不配置浏览器的情况下构建本地 Web 代理

    Netnanny 或 k9 Web Protection 如何在不配置浏览器的情况下设置 Web 代理 如何做呢 直接使用WinSock 或者在NDIS http en wikipedia org wiki Network Driver I
  • ARM 模板数组参数

    我有一个带有 Web 应用程序警报规则的 ARM 模板 我希望能够在其中配置哪些电子邮件收到警报 电子邮件警报操作的片段如下 action odata type Microsoft Azure Management Insights Mod
  • 检测到可能存在 DNS 欺骗。远程主机标识已更改

    我最近更换了服务器 因此我有了一个新的 IP 地址 当我尝试使用时git fetch remote repository 我明白了 gt C Users path app gt git fetch remote repository gt
  • Java RMI 和 RPC 有什么区别?

    Java RMI 和 RPC 之间的实际区别是什么 我在一些地方读到 RMI 使用对象 RPC是基于C的 因此它具有结构化编程语义 另一方面 RMI是基于Java的技术 并且是面向对象的 通过 RPC 您可以调用导出到服务器中的远程函数 在
  • 检测麦克风是否打开

    有没有办法以编程方式检测 Windows 上的麦克风是否打开 不 麦克风不会告诉您它们是否 打开 或者特定的声道是否已连接到麦克风设备 您能做的最好的事情就是从您怀疑是麦克风的输入通道 例如Windows默认输入设备 通道 读取音频数据 并
  • 如何获取数据列表的更改事件?

    我正在使用数据列表 需要检测用户何时从下拉列表中选择某些内容 类似的问题已被问到 https stackoverflow com questions 16027746 jquery event when html5 datalist opt
  • 将 SVG 图像转换为 png 以供不支持的浏览器使用 - 后备 - Modernizer.js(?) [重复]

    这个问题在这里已经有答案了 我正在考虑转几个SVG我的网站上的图像PNG对于不支持的浏览器SVG适当地 我主要对显示的基于文本的问题有疑问IE 显示的字体完全错误 所以我想我应该创建一个后备PNG 我已经尝试为此寻找一个很好的演练 我自认是
  • 使用函数式编程有效地计算素数

    通过回顾 Project Euler 并解决一些问题 我逐渐熟悉了 F 许多早期问题都由素数组成 环顾四周后 我想出了以下解决方案 let primesL let rec prim n sofar seq if sofar gt List
  • 如何在拖动 UICollectionViewCell 时实现透明背景或圆角

    我确定有must这是一种简单的方法 但我已经花了很长时间在各种兔子洞里 到目前为止还没有成功 我有一个支持拖放的集合视图 被拖动的单元格有一个UIImageView in the contentView 并且图像视图的背衬层应用了角半径 单
  • 如果其中一个进程意外终止,进程间内存会发生什么情况?

    如果您对动机感兴趣 我将在接下来的几句话中详细说明 如果不是 请跳至问题 我正在考虑制作快速记录器 但当程序崩溃时不受影响 又名最后一些日志消息不会丢失 所以我的想法是写入共享内存 ringbuffer 并让另一个低优先级进程从中读取并进行
  • 如何在jsf中启用浏览器缓存

    我使用 JSF 2 0 创建了一个 Web 应用程序 我收到朋友的反馈说我应该执行 浏览器缓存 因为我有很多图像 但是我不知道如何在 JSF 中做同样的事情 任何想法 提示将不胜感激 关于要做什么的概念也会起作用 只需使用
  • 继承和多态性的低级细节

    这个问题是我心中的一大疑惑 也很难用语言来形容 有时它看起来很明显 有时却很难破解 所以问题是这样的 class Base public int a number Base virtual void function1 virtual vo