虚函数和多态性

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(使用前将#替换为@)

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

  • 结构体如何存储在内存中?

    我有一个struct iof header在我的代码中 我确定它的宽度是 24 字节 我执行 sizeof iof header 它返回 32 字节宽 问题1为什么是 32 字节宽而不是 24 字节宽 问题2包括其成员在内 结构体如何存储在
  • .NET 单点登录

    我一直在尝试使用 C 为 NET Web 应用程序实现 WEB SSO 服务提供程序插件 我将使用 shibboleth 身份提供商 我已经使用 OpenSAML 库为 java 应用程序实现了相同的功能 我想知道在 NET 应用程序中使用
  • 深拷贝和动态转换 unique_ptr

    假设我有一个如下所示的类 class A virtual A class B public A class C public A 我还有一个 unique ptr 向量 它是这样声明的 std vector
  • 将字符串作为 PChar 从 CSharp 传递到 Delphi DLL

    我正在尝试将字符串从 C 传递到 Delphi 构建的 DLL Delphi DLL 需要 PChar 这是Delphi导出 procedure DLL Message Location PChar AIntValue integer st
  • 警告 C4800:“int”:强制值为 bool“true”或“false”(性能警告)

    我的代码中有这个问题 bool CBase isNumber return id MID NUMBER bool CBase isVar return id MID VARIABLE bool CBase isSymbol return i
  • 局部函数声明有什么用处吗?

    大多数像我这样的 C 程序员都曾犯过以下错误 class C int main C c declares a function c taking no arguments returning a C not as intended by m
  • Dapper 在执行时挂起

    我有一个 IDb连接 sql UPDATE 表名 SET json json lastupdate SYSDATE WHERE id id var param new DynamicParameters param Add json jso
  • 在没有 epsilon 的情况下可以将浮点数与 0.0 进行比较吗?

    我知道 要比较两个浮点值 需要使用一些 epsilon 精度 因为它们并不精确 但是 我想知道是否存在边缘情况 我不需要那个 epsilon 特别是 我想知道这样做是否总是安全的 double foo double x if x lt 0
  • ASP.NET - 在 RenderContent 调用中将事件处理程序添加到 Repeater 内的 LinkBut​​ton

    我有一个加载自定义用户控件的 Sharepoint WebPart 用户控件包含一个 Repeater 而 Repeater 又包含多个 LinkBut ton 在 Web 部件的 RenderContent 调用中 我有一些用于添加事件处
  • Visual Studio 中列表框的上移、下移按钮[重复]

    这个问题在这里已经有答案了 我正在尝试制作一个上移按钮和一个下移按钮 以移动 Microsoft Visual Studio 2012 中列表框中的选定项目 我已经在 WDF jquery winforms 和其他一些表单中看到了其他示例
  • 控制台应用程序中使用 Unicode 字符的 _tprintf

    我正在从 Unicode 构建的控制台应用程序 使用 C 和 Visual Studio 2008 执行这个简单的输出 此代码旨在在 Windows 上运行 tprintf L Some sample string n 一切正常 但是如果我
  • 在c#中获取没有时间的日期

    我的表上有一列 缺勤日期时间 日期 当我想要获取包含日期的行时 它返回 0 行 这是我的 C 代码 DateTime ClassDate DateTime Parse lblDate Content ToString var Abs dbs
  • 配置:错误:无法运行C编译的程序

    我正在尝试使用 Debian Wheezy 操作系统在我的 Raspberry Pi 上安装不同的软件 当我运行尝试配置软件时 我尝试安装我得到此输出 checking for C compiler default output file
  • 从 DataRow 单元格解析 int [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 如何从 DataRow 单元格解析 int 值 Int32 Parse item QuestionId ToString 这段代码可以工作 但看
  • C++ 中是否有与 PHP 的explode() 函数等效的函数? [复制]

    这个问题在这里已经有答案了 可能的重复 在 C 中分割字符串 https stackoverflow com questions 236129 splitting a string in c 在 PHP 中 explode 函数将获取一个字
  • 连接到没有元数据的网络服务

    我想连接到此网络服务 https training api temando com schema 2009 06 server wsdl https training api temando com schema 2009 06 serve
  • “1个未解决的外部”C++

    我已经检查了所有文件之间的连接以及类和函数定义 但每次我尝试运行我的程序时 它都会阻止我并告诉我它有 1 个未解析的外部 该程序应该打开多个文件 一个 学生 文件和一个 成绩 文件 从中读取数据 然后使用 查询文件 来查找数据 找到查询中要
  • Xcode 7 调试器不会中断内联标头函数

    过去五年我一直在各种 C 项目中使用 Xcode 没有出现这个问题 今天 我打开了一个较旧的项目 大约 2 年前 并尝试通过在该函数中放置一个活动断点来调试头文件中的内联函数 由于某种原因 调试器不会中断此代码 但是 如果我在调用该函数的
  • 卸载程序

    我正在尝试使用此代码卸载程序 但它似乎不起作用 我尝试过其他答案 但似乎也不起作用 有人可以帮助我吗 我正在尝试按给定名称 displayName 卸载该程序 例如 我给出 displayName Appname 那么此代码应该从我的计算机
  • 为什么在构造函数中设置字段是(或不是)线程安全的?

    假设您有一个像这样的简单类 class MyClass private readonly int a private int b public MyClass int a int b this a a this b b public int

随机推荐

  • 如何使用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类