虚函数和多态性

2023-12-07

假设我有这个:

class A
{
    public:
    virtual int hello(A a);
};

class B : public A
{
   public:
   int hello(B b){ bla bla };
};

所以,A是一个抽象类。

1)在B类中,我定义了一个假设覆盖A类的方法。但参数略有不同。我不确定这一点,这是正确的吗?也许因为多态性,这没关系,但相当混乱。 2)如果我这样做:A a = new B;,然后a.hello(lol);如果“lol”不是 B 类型,那么它会给出编译错误?如果它是另一个 C 类(C 类:公共 A)的 A 类型,会发生什么?

我对最重要的和虚拟的东西感到困惑..我发现的所有示例都适用于没有参数的方法。

任何答案、链接或任何值得赞赏的内容。

thanks

pd:对不起我的英语


你的B级没有overrideA 中的成员函数,它超载它。或者尝试无论如何,稍后再看看有关隐藏的内容。

重写是指派生类从基类定义其自己的虚拟成员函数版本。重载是指定义具有相同名称的不同函数。

当对具有基类类型的指针或引用进行虚拟调用时,它只会“考虑”派生类中的重写,而不是重载。这是至关重要的 - 对于调用者对待 B 的实例来说,就好像它做了 A 可以做的所有事情(这是动态多态性和虚函数的要点),它的hello函数需要能够接受 A 类型的任何对象。hello仅接受 B 类型对象而不是任何 A 类型对象的函数更具限制性。发挥不了A的作用hello函数,所以它不是覆盖。

如果你尝试一下打电话hello在 A 和 B 上,传递 A 或 B 类型的对象,您应该能够看到差异。 A 有一个接受 A 的函数(您尚未定义该函数,因此如果您调用它,那么您的程序将无法链接,但您可以修复该问题)。 B 有一个采用 B 的函数。它们碰巧具有相同的名称,当然,由于 B 派生自 A,因此您可以将 B 传递给采用 A 的函数。但是 B 的函数在虚拟调用中不充当覆盖。

可以在 B 对象上调用 A 的函数,但只能通过 A 的引用或指针。C++ 的一个功能是定义helloB 中隐藏了 A 中的定义。如果您想要重载,可以通过添加来取消隐藏基类函数using A::hello;到 B 类。如果您想要覆盖,则必须定义一个采用相同参数的函数。例如:

#include <iostream>

class A
{
    public:
    virtual int hello(A a) {std::cout << "A\n"; }
    virtual int foo(int i) { std::cout << "A::Foo " << i << "\n"; }
};

class B : public A
{
   public:
   using A::hello;
   // here's an overload
   int hello(B b){ std::cout << "B\n"; };
   // here's an override:
   virtual int foo(int i) { std::cout << "B::Foo " << i << "\n"; }
};

int main() {
    A a;
    B b;
    a.hello(a);  // calls the function exactly as defined in A
    a.hello(b);  // B "is an" A, so this is allowed and slices the parameter
    b.hello(a);  // OK, but only because of `using`
    b.hello(b);  // calls the function exactly as defined in B
    A &ab = b;   // a reference to a B object, but as an A
    ab.hello(a); // calls the function in A
    ab.hello(b); // *also* calls the function in A, proving B has not overridden it
    a.foo(1);    // calls the function in A
    b.foo(2);    // calls the function in B
    ab.foo(3);   // calls the function in B, because it is overridden
}

Output:

A
A
A
B
A
A
A::Foo 1
B::Foo 2
B::Foo 3

如果你拿走using A::hello;来自 B 的线路,然后呼叫b.hello(a);编译失败:

error: no matching function for call to `B::hello(A&)'
note: candidates are: int B::hello(B)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

虚函数和多态性 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 传递给函数时多维数组的指针类型是什么? [复制]

    这个问题在这里已经有答案了 我在大学课堂上学习了 C 语言和指针 除了多维数组和指针之间的相似性之外 我认为我已经很好地掌握了这个概念 我认为由于所有数组 甚至多维 都存储在连续内存中 因此您可以安全地将其转换为int 假设给定的数组是in
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • 如何使用C#从Excel文件中读取数据[重复]

    这个问题在这里已经有答案了 我的应用程序需要从 Excel 文件读取数据 我使用 Net 和 c 进行开发 我无法在系统中安装MS Office 因此 我的应用程序无法读取 excel 文件 并在加载 excel 的 dll 时抛出错误 如
  • 如何恢复已推送到远程的合并提交?

    git revert
  • 将手柄传递到管道中

    说我有 node foo js node bar js 有没有办法将 foo 的标准输入句柄传递给 bar js 我有一个罕见的情况 我想在管道中进行向后通信 至少我知道我可以发送node bar js的pidnode foo js 鉴于
  • 在python中访问字典的字典

    你好 在我的代码中有一个字典的字典 nrec bridge xapi1 current operations uuid 9ae5ca7d e7d6 7a81 f619 d0ea33efb534 tags other config is gu
  • Google Play 游戏服务 - 如何在暂停时不留空间

    我不知道为什么 https stackoverflow com questions 18142763 is it possible to show full screen activity without leaving room usin
  • ISO 8601 周数(C 语言)

    我正在尝试使用 C 获取 ISO8601 周数 我的 PC 上安装了 MinGW GCC 版本是 5 3 0 你可以在下面看到我的代码 strftime不适用于说明符 V 但它与说明符 W 一起工作得很好 但这不是我想要的 我需要 ISO
  • 测试后清除 Spring 应用程序上下文

    如何使用 Junit5 和 Spring Boot 在每次测试执行后清除应用程序上下文 我希望在测试中创建的所有 bean 在执行后都被销毁 因为我在多个测试中创建相同的 bean 我不想为所有测试使用一个配置类 而是为每个测试使用一个配置
  • 我可以同时使用 Twitter Bootstrap 和 jQuery UI 吗?

    我正在使用 Twitter Bootstrap 我想使用 Bootstrap 中不可用的 自动建议 而 jQuery UI 有自己的自动建议方法 我可以同时使用两者吗 会导致带宽超载吗 查看jquery ui 引导程序 来自自述文件 Twi
  • Rust impl Trait 作为函数返回类型[重复]

    这个问题在这里已经有答案了 我有以下功能 其中Command是一种特质 pub fn parse arguments matches ArgMatches gt Result
  • CancellationToken 的竞争条件,其中 CancellationTokenSource 仅在主线程上取消

    考虑一个 Winforms 应用程序 其中我们有一个可以生成一些结果的按钮 如果用户第二次按下该按钮 则应取消第一个生成结果的请求并开始新的请求 我们正在使用以下模式 但我们不确定某些代码是否是防止竞争条件所必需的 请参阅注释掉的行 pri
  • 使用officer包编辑Word表格

    我正在尝试使用 officer 编辑Word表格的值 非常简单地找到包含它的 段落 library officer doc read docx template docx doc cursor begin doc doc cursor re
  • 需要格式化 JAXB 输出的帮助

    我有一些对象 比如说两个 A 和 B 这些对象来自同一类 我需要使用 JAXB 封送这些对象 并且输出 XML 应采用以下形式
  • Java SE 还是 Java EE(标准或企业)?

    我开始做大量 Java EE 开发工作 可以在我的家用计算机上安装 Java EE 而不是 JRE 吗 另外 GlassFish 可以在 JRE 上运行还是需要 Java EE Java EE 是一个抽象 API GlassFish 是可用
  • 防止更新禁用视图上的注释/文件

    我注意到当网格不允许更新 插入或删除时 可以在网格上插入 更新 删除注释和文件 假设形式相同 有办法关掉它吗 我正在编写一个自定义页面 并希望阻止用户修改任何内容 包括注释和文件 我的网格包含以下内容 MyGrid AllowInsert
  • C++ 中的多重调度

    我想了解什么是多重调度 我读了很多不同的文本 但我仍然不知道多重调度是什么以及它有什么好处 也许我缺少的是使用多重调度的代码片段 请问 您能否使用多重分派在 C 中编写一小段代码 以便我可以看到它无法正确编译 运行 因为 C 只有单分派 我
  • 为 azure vm 和 godaddy 配置自定义域名

    最近我开始在 azure 配置我的虚拟机 我使用 nginx 部署了 4 个项目 但在使用 godaddy 配置我的虚拟机时遇到了问题 要在 Godaddy 中配置域名 我需要设置至少 2 个 DNS 地址 但我的虚拟机只有 1 个 DNS
  • 液体和算术

    我正在研究一些分页 我想知道是否有办法告诉 Liquid 只显示 5 页 我正在寻找的输出是 78 9 最后 gt gt 我目前的逻辑有效 但它显示了所有 30 个页面 for count in 2 paginator total page
  • ggplot2:geom_smooth 选择观测值连接(相当于 geom_path())

    我在用ggplot2创建海洋的垂直剖面 我的原始数据集创建 尖峰 以便形成平滑的曲线 我希望使用geom smooth 我还希望线条根据观察的顺序 而不是根据 x 轴 进行 当我使用geom path 它适用于原始情节 但不适用于结果geo
  • Postgres:使用游标更新的令人惊讶的性能

    考虑以下两个 Python 代码示例 它们实现了相同的效果 但具有显着且令人惊讶的性能差异 import psycopg2 time conn psycopg2 connect dbname mydatabase user postgres
  • 虚函数和多态性

    假设我有这个 class A public virtual int hello A a class B public A public int hello B b bla bla 所以 A是一个抽象类 1 在B类中 我定义了一个假设覆盖A类