【C++基础入门】42.C++中同名覆盖引发的问题

news2024/9/22 23:37:17

一、父子间的赋值兼容

  • 子类对象可以当作父类对象使用(兼容性)
    • 子类对象可以直接赋值给父类对象
    • 子类对象可以直接赋值给父类对象
    • 父类指针可以直接指向子类对象
    • 父类引用可以直接引用子类对象

        下面看一个子类对象兼容性的代码:

#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:
    int mi;
    
    void add(int i)
    {
        mi += i;
    }
    
    void add(int a, int b)
    {
        mi += (a + b);
    }
};

class Child : public Parent
{
public:
    int mv;
    
    void add(int x, int y, int z)
    {
        mv += (x + y + z);
    }
};

int main()
{
    Parent p;
    Child c;
    
    p = c;
    
    Parent p1(c);
    
    
    Parent& rp = c;
    Parent* pp = &c;
    
    rp.mi = 100;
    rp.add(5);             // 没有发生同名覆盖?
    rp.add(10, 10);        // 没有发生同名覆盖?
    
    /* 为什么编译不过? */
    // pp->mv = 1000;
    // pp->add(1, 10, 100);
    
    return 0;
}

        其中下面的代码可以正常编译,没有发生同名覆盖

 rp.mi = 100;
 rp.add(5);             // 没有发生同名覆盖?
 rp.add(10, 10);        // 没有发生同名覆盖?

        而下面的代码编译不过

// pp->mv = 1000;
// pp->add(1, 10, 100);

         下面揭晓答案:

  • 当使用父类指针(引用)指向子类对象时
    • 子类对象退化为父类对象
    • 只能访问父类中定义的成员
    • 可以直接访问被子类覆盖的同名成员

二、特殊的同名函数

  • 子类中可以重定义父类中已经存在的成员函数
  • 这种重定义发生在继承中,叫做函数重写
  • 函数重写是同名覆盖的一种特殊情况

思考:函数重写遇上赋值兼容会怎么样?

        下面看一个赋值兼容的代码:

#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:
    int mi;
    
    void add(int i)
    {
        mi += i;
    }
    
    void add(int a, int b)
    {
        mi += (a + b);
    }
    
    void print()
    {
        cout << "I'm Parent." << endl;
    }
};

class Child : public Parent
{
public:
    int mv;
    
    void add(int x, int y, int z)
    {
        mv += (x + y + z);
    }
    
    void print()
    {
        cout << "I'm Child." << endl;
    }
};

void how_to_print(Parent* p)
{
    p->print();
}

int main()
{
    Parent p;
    Child c;
    
    how_to_print(&p);    // Expected to print: I'm Parent.
    how_to_print(&c);    // Expected to print: I'm Child.
    
    return 0;
}

        输出结果如下:

  • 问题分析
    • 编译期间,编译器只能根据指针的类型判断所指向的对象
    • 根据赋值兼容,编译器认为父类指针指向的是父类对象
    • 因此,编译结果只可能是调用父类中定义的同名函数

        在编译这个函数的时候,编译器不可能知道指针 p 究竟指向了什么。但是编译器没有理由报错。于是,编译器认为最安全的做法是调用父类的 print 函数,因为父类和子类肯定都有相同的 print 函数。

问题:编译器的处理方法是合理的吗?是期望的吗?

        编译器的处理方法是合理的,但不是我们期望的,我们期望的是子类对象调用子类的 printf 函数,父类对象调用父类的 printf 函数

三、小结

  • 子类对象可以当作父类对象使用(赋值兼容)
  • 父类指针可以正确的指向子类对象
  • 父类引用可以正确的代表子类对象
  • 子类中可以重写父类中的成员函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1134850.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EasyConnect

EasyConnect 简介下载安装 简介 EasyConnect 是一种远程连接解决方案&#xff0c;它允许用户通过互联网远程访问和控制其设备和资源。 下载 链接: https://pan.baidu.com/s/1JvejSUA8Tma91FOUv6Gswg 提取码: 3fb5 安装

7-4、S加减速转动实现【51单片机控制步进电机-TB6600系列】

摘要&#xff1a;本节介绍实现步进电机S曲线运动的代码 一、目标功能 实现步进电机转动总角度720&#xff0c;其中加减速各90 加速段&#xff1a;加速类型&#xff1a;S曲线   加速角度&#xff1a;角度为90   起步速度&#xff1a;30RPM&#xff0c;   终止速度&#x…

现在java和大数据选什么?

现在java和大数据选什么&#xff1f; 到底是选择大数据还是JAVA&#xff1f;”相信这个问题困惑着许多转行待定人士和高校专业待选的学生。 在普通人眼里可能会觉得这两个专业或者行业没啥区别&#xff0c;都是IT里的&#xff0c;能有啥大不同。这是第一层。最近很多小伙伴找我…

Linux系统中让$前面显示完整的路径

目录 ■修改前效果 ■修改后效果 ■修改方法 ■修改前效果 ■修改后效果 ■修改方法 step1.找到当前用户下面的配置文件【.bashrc】 step2.使用vi命令编辑文件&#xff0c;在最后一行添加如下内容。 export PS1[\u\h $PWD]$ step3.使修改后的文件立即生效 source .bashrc

叮~程序员,你的专属1024程序员节已到账,请注意查收!

“1024&#xff0c;怎么过&#xff1f;” “&#xff1f;&#xff1f;&#xff1f;” “呆子。程序员节&#xff01;” 鲁迅曾说&#xff1a;世界上本没有节日&#xff0c;关注的人多了&#xff0c;便成了节。(hahaha....bushi) 如此小众的节日&#xff0c;外行的人听了好奇&a…

uboot通过图像化界面配置 dns命令

一. 简介 之前文章简单介绍了 uboot图像化配置操作。地址如下&#xff1a; uboot图像化配置操作说明-CSDN博客 本文就以如何使能 dns 命令为例&#xff0c;讲解一下如何通过图形化界面来配置 uboot。 二. uboot 通过图像化界面配置 dns命令 这里所使用的 uboot的源码包&…

M1本地部署Stable Diffusion

下载安装 参考博客: 在Mac上部署Stable Diffusion&#xff08;超详细&#xff0c;AI 绘画入门保姆级教程&#xff09; 安装需要的依赖库 brew install cmake protobuf rust python3.10 git wget 可能中途会存在下载报错或者下载卡主的问题,需要切国内源 brew进行替换源: …

小黑子—spring:第一章

spring入门1.0 一 小黑子对spring基础进行概述1.1 spring导论1.2 传统Javaweb开发困惑及解决方法1.3 三大的思想提出1.3.1 IOC入门案例1.3.2 DI入门案例 1.4 框架概念1.5 初识spring1.5.1 Spring Framework 1.6 BeanFactory快速入门1.7 ApplicationContext快速入门1.8 BeanFact…

SpringBoot项目中的测试类,无法注入类,注入类为空

开发中&#xff0c;需要用到测试类来测试接口 我最开始使用的注入方式是Autowired&#xff0c;但是在执行测试时&#xff0c;注入类报空指针异常&#xff0c;一直为null 后来上网查到几种解决方案&#xff0c;最终在通过下述内容解决了&#xff1a; 1.测试类中添加注解 SpringB…

【云上探索实验室-码上学堂】免费学习领好礼!

走过路过&#xff0c;不要错过&#xff01;上云AI三步走&#xff0c;学着课程奖品有&#xff01; 亚马逊云科技又放福利了&#xff0c;为了让同学们更快入手Amazon CodeWhisperer&#xff0c;官方推出《云上探索实验室-码上学堂》活动&#xff0c;作为一名Amazon CodeWhisperer…

一种晶圆表面形貌测量方法-无图晶圆几何量测系统

晶圆检测机&#xff0c;又称为半导体芯片自动化检测设备&#xff0c;是用于对半导体芯片的质量进行检验和测试的专用设备。它可以用于硅片、硅晶圆、LED芯片等半导体材料的表面检测&#xff0c;通过对晶圆的表面特征进行全面检测&#xff0c;可以有效降低产品的不良率&#xff…

Z41H-40C明杆闸阀型号解析

Z41H-40C型号字母含义 Z41H-40C型号是德特森阀门常用的明杆闸阀型号字母分别代表的意思是: Z——代表阀门类别《闸阀》 4——代表连接方式《法兰》 1——代表结构形式《明杆》 H——代表密封材质《不锈钢合金》 -《分隔键》 40——代表公称压力《4.0MPA》 C——代表阀体…

MongoDB副本集调整节点

点击上方蓝字关注我 MongoDB的副本集&#xff08;Replica Set&#xff09;是一个高可用性、可扩展性和冗余性的数据库解决方案。它能够确保数据库的高可用性&#xff0c;同时保障了数据的安全性。在本文中&#xff0c;我们将探讨如何在一个已经包含三个数据节点的副本集集群中&…

前端(二十四)——轮询与 WebSocket的battle

&#x1f603;博主&#xff1a;小猫娃来啦 &#x1f603;文章核心&#xff1a;轮询与 WebSocket的battle 文章目录 前言轮询的原理及实现WebSocket的原理及实现轮询与WebSocket的比较轮询的应用场景WebSocket的应用场景使用场景的对比与选择WebSocket的安全性考虑WebSocket与服…

匝间冲击耐压试验仪

概述 武汉凯迪正大KDYD2835kV匝间冲击耐压试验仪是采用脉冲波形比较法,以高压冲击波对二线圈或绕组进行过电压的模拟检测&#xff0c;并由示波器来判别二绕组波形差异的一种测试仪器。它能迅速、正确地判断线圈或绕组匝间绝缘电晕放电、局部或相间短路、开路、接线嵌线错误、线…

正点原子嵌入式linux驱动开发——Linux I2C驱动

在电子产品硬件设计当中&#xff0c;I2C 是一种很常见的同步、串行、低速、近距离通信接口&#xff0c;用于连接各种IC、传感器等器件&#xff0c;它们都会提供I2C接口与SoC主控相连&#xff0c;比如陀螺仪、加速度计、触摸屏等&#xff0c;其最大优势在于可以在总线上扩展多个…

uniapp开发小程序—根据生日日期计算年龄 周岁

0、需求 在UniApp开发小程序中&#xff0c;将接口返回的出生日期转化为年龄&#xff1b;判断接口返回的年龄是否是周岁 可以使用JavaScript的日期处理方法来实现。 一、第一种方式&#xff08;示例代码&#xff09;&#xff1a; //javascript // 假设接口返回的年龄为生日的…

源代码转换:Tangible Software Solutions 23.10 Crack

Tangible Software Solutions The Most Accurate and Reliable Source Code Converters Convert between C#, Java, C, Python, & VB, while saving countless hours of painstaking work and valuable time.源代码转换 Key Benefits Saves valuable time Accurate and com…

美摄人像背景抠图SDK

企业对于图像处理的需求越来越高。无论是社交媒体营销、产品展示还是企业内部培训&#xff0c;高质量的图像都是吸引用户和提升品牌形象的关键。然而&#xff0c;传统的图像处理工具往往需要大量的手动操作和专业技巧&#xff0c;耗时耗力。为了满足企业对于高效、精准的图像处…

LVS+keepalived——高可用集群

LVSkeepalived——高可用集群 keppalived为lvs应运而生的高可用服务。lvs的调度器无法做高可用&#xff0c;于是keepalived这个软件。实现的是调度器的高可用。 但是&#xff1a;keepalived不是专门为lvs集群服务的。也可以做其他代理服务器的高可用。 lvs的高可用集群是建立…