C++中关于隐藏的理解

2023-11-15

引言

在使用中弄清楚隐藏的区别之后,还需要明白怎么使用。下面说以下隐藏,重写,重载的区别:
与重载的区别:

在父类与子类中,函数名相同,参数不同,无论父类中的同名函数是否含有virtual关键字,都是隐藏;

与重写的区别:

在父类和子类中,函数名相同,参数相同,父类中的同名函数没有virtual关键字,为隐藏。

示例

下面举例说明:

class Base
{
	public:
	void funA(){cout<<"funA()"<<endl;}
	virtual void funB(){cout<<"funB()"<<endl;} 
};

class Heri:public Base
{
	public:
	void funA(){cout<<"funA():Heri"<<endl;}
	void funA(int a){cout<<"funA(int a):heri"<<a<<endl;}
	void funB(){cout<<"funB():heri"<<endl;}
};

以上示例中,基类中的函数funA()与派生类中的函数funA()之间是隐藏,其函数名相同,参数相同,存在于派生类于子类中,且基类中的funA()函数前没有virtual关键字,故为隐藏。基类的函数funA()与派生类中的函数funA(int a)函数名相同,参数不同,存在于基类和派生类中,无论基类有没有关键字virtual两个函数之间也是隐藏,基类函数funB()与派生类函数funB()之间是重写,又叫覆盖,当重写发生的情况下,父类的指针或引用指向子类的对象,通过父类的指针或引用调用父子类中被重写的函数,实际上调用的是子类的函数,这个具体得理解虚函数,多态这块,这里不再提及。以上是对函数之间关系的一种分析,接下来应该看看如何使用隐藏,隐藏使用的时候记住一句,派生类的指针或引用,对象调用子类和父类同名的函数,父类的同名函数被子类隐藏,调用的是子类的函数,当然这句话是针对于隐藏关系的函数的而言。接下来看如何应用。

隐藏的应用

下面是一个小程序,上代码:

// hideDemo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <stdlib.h>

using namespace std;

class Base
{
public:
    void fun1(){cout<<"base:fun1()"<<endl;fun();}
    virtual void fun(){cout<<"base:fun()"<<endl;}
};

class Deriverd:public Base
{
public:
    virtual void fun1(){cout<<"deriverd:fun1()"<<endl;}
    void fun(){cout<<"deriverd:fun()"<<endl;}
};

int _tmain(int argc, _TCHAR* argv[])
{
	Base *pb = new Deriverd;
    pb->fun1();


    system("pause");
    return 0;
}

上面是一个小程序,输出结果为:
在这里插入图片描述
之所以输出是上面的结果是因为main函数中创建了父类的指针指向了子类的对象,然后通过父类的指针调用具有隐藏关系的fun1()函数,该函数在使用时记住一句“派生类的指针,引用,对象调用父类或者派生类中的同名函数,调用的是子类的函数”,这句话一听就会被误解,pb->fun1();以为调用的是子类的函数fun1(),实际并不是,上句话有一个前提,是派生类的对象或引用,指针进行调用,而这里是父类的指针调用,这样的解释过于牵强,我总结出的经验就是,隐藏关系的函数,谁调用就用谁的函数,按照正常的函数调用使用便可得正确的结果,这里是父类指针调用,就用父类的函数fun1().当然这只适用于作答,真正的理解还得从书上给出的解释入手。

巩固

下面基于上面的理解,看看下面的程序:

// hideDemo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <stdlib.h>

using namespace std;

class Base
{
public:
    void fun1(){cout<<"base:fun1()"<<endl;fun();}
    virtual void fun(){cout<<"base:fun()"<<endl;}
};

class Deriverd:public Base
{
public:
    virtual void fun1(){cout<<"deriverd:fun1()"<<endl;}
    void fun(){cout<<"deriverd:fun()"<<endl;}
};

int _tmain(int argc, _TCHAR* argv[])
{
	Base *pb = new Deriverd;
    pb->fun1();
    Deriverd de;
    de.fun1();
    Base b;
    b.fun1();


    system("pause");
    return 0;
}

输出结果:
在这里插入图片描述
定义派生类对象Deriverd de;通过派生类对象调用fun1(),这里调用的是派生类自己的函数fun1(),应了那句“派生类的对象,指针,引用调用派生类和基类的同名函数,调用的是派生类的函数,父类的函数被隐藏”,定义基类对象 Base b;通过对象b调用函数fun1(), 调用的是基类的函数fun1().然后在fun1()中输出base:fun1(),接着调用函数fun(),这里的函数fun()调用的是基类自身的函数fun(),因为没有此时没有涉及到多态,这里是父类的对象调用的,不是父类的指针,或者引用调用。

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

C++中关于隐藏的理解 的相关文章

随机推荐

  • Linux添加组播

    sudo route add net 224 1 1 0 netmask 255 255 255 0 dev ens33 转载于 https www cnblogs com tiandsp p 10985838 html
  • 鲁棒优化(4):通过yalmip中的kkt命令实现CCG两阶段鲁棒优化

    两阶段鲁棒优化的原理推导部分 已经较多的文章进行分析 目前大部分同学面临的问题是 子问题模型中存在的双线性项该如何处理 目前 主流方式是 采用对偶定理或KKT条件 将第二阶段的双层问题变成单层问题 简略的思想如下 首先是原始的两阶段模型 对
  • c++中std::condition_variable最全用法归纳

    前言 建议阅读以下文章前需先对建立 std thread 多线程与std mutex 锁有一定程度的熟悉 std thread最全用法归纳 std mutex最全用法归纳 概括 使用 std condition variable 的 wai
  • 【代码分析】TensorRT sampleMNIST 详解

    目录 前言 代码分析 Main入口 网络构建 build 阶段 网络推理 infer 阶段 释放资源 前言 TensorRT 的 hello world 程序sampleMNIST是众多TensorRT初学者很好的起点 本文旨在详细分析sa
  • 使用PHP来简单的创建一个RPC服务

    RPC全称为Remote Procedure Call 翻译过来为 远程过程调用 主要应用于不同的系统之间的远程通信和相互调用 比如有两个系统 一个是PHP写的 一个是JAVA写的 而PHP想要调用JAVA中的某个类的某个方法 这时候就需要
  • VScode tab缩进太小 空格长度太小问题(Ubuntu)

    一 问题描述 Ubuntu18 04 安装vscode后 发现tab的缩进太小 初以为是tab的空格数没设置对 经确认后 没问题 一个tab是四个空格 下面两图分别是异常和正常的缩进显示 二 原因分析 在我的另一台虚拟机 ubuntu16
  • Google App Engine对Java支持情况一览

    Google App Engine对Java支持情况一览 http developer 51cto com 2009 04 09 11 06 杨赛 译 51CTO com 我要评论 0 Google App Engine的Java支持已发布
  • 华为OD机试-快递运输

    Online C compiler to run C program online include
  • Java程序的三种流程结构

    1 顺序结构 按照顺序一句一句执行 Java的基本结构就是顺序结构 2 循环结构 在顺序结构的基础下 重复执行相同或者相似的代码 for while do while 3分支结构 有条件的去执行某个语句 条件满足就执行下面的语句 条件不满足
  • SQL注入攻击流程

    1 判断SQL注入点 本质原理是 找一个需要后台处理后提交给数据库的点 所有的输入只要和数据库进行交互的 都有可能触发SQL注入 一般为三大类 Get参数触发SQL注入 POST参数触发SQL注入 Cookie触发SQL注入 而验证是否存在
  • 华为手机打开图片很慢是怎么回事_华为手机相册打开很慢怎么解决?

    造成卡顿的原因 相册里存储信息较多 由于手机读取相册中的信息需要一定时间 可能出现卡顿现象 系统卡顿通用解决办法 请保持手机电量高于 20 手机低电量时为了延长待机时间 保护手机 会对手机的性能进行限制 卸载第三方手机管家类软件 如果您的手
  • 【Python】首届一年一度秀代码时间罒ω罒

    声明 以下代码大家如果有兴趣的话可以用LDLE代码编辑器运行看看 NO 1 万能计算器 难度系数 1 算术运算符 a input 请输入第一个数字 b input 请输入第二个数字 a float a b float b print 和 a
  • 小韭菜

    大家好 我是章鱼猫 今天给大家推荐的这个项目是 leeks 原名小韭菜 后改名为 leeks 这是一个 IDEA 查看股票 基金插件 写代码的同时还能瞄一眼股票 基金 真的是工作 搞基两不误 安装 下载当前最新的安装包 leeks 1 3
  • 解决 linux在 VMware中的问题 汇总 (***)

    目录 解决Ubuntu在VMware中不能全屏的问题 无需安装 VMware tools 解决虚拟机与宿主机的文件共享问题 Ubuntu Window下 X2Go 安装 连接 同步 上传文件夹 复制 粘贴 桌面共享 Linux挂载共享文件夹
  • 命令行中Gradle创建项目的打包和运行,新手起步

    第一步 下载 下载 https gradle org 官网 gt install gt releases page gt binary only 下载 下载页 https gradle org releases close notifica
  • vue中在字符串中添加点击事件

    如果你在用vue写项目中遇到了需要在字符串中写点击事件的奇葩写法 你会不会感到很头疼 我不知道你会不会 反正我肯定会 没办法谁叫咋遇到了呢 话不多说 直接上代码 html div class ml 12 mr 12 mt 8 div 采用的
  • 华为OD机试 - 可以组成网络的服务器(Java)

    题目描述 在一个机房中 服务器的位置标识在 n m 的整数矩阵网格中 1 表示单元格上有服务器 0 表示没有 如果两台服务器位于同一行或者同一列中紧邻的位置 则认为它们之间可以组成一个局域网 请你统计机房中最大的局域网包含的服务器个数 输入
  • Docker-compose安装及使用教程

    docker compose安装 方法一 首先执行pip V确认是否已安装pip 若提示 未找到命令 则根据以下步骤执行 若显示pip版本则直接执行步骤2安装即可 1 安装pip wget https bootstrap pypa io g
  • SpringBoot 中定时执行注解(@Scheduled、@EnableScheduling)

    项目开发中经常需要执行一些定时任务 比如需要在每天凌晨时候 分析一次前一天的日志信息 Spring为我们提供了异步执行任务调度的方式 提供TaskExecutor TaskScheduler 接口 SpringBoot中使用两个注解 Ena
  • C++中关于隐藏的理解

    引言 在使用中弄清楚隐藏的区别之后 还需要明白怎么使用 下面说以下隐藏 重写 重载的区别 与重载的区别 在父类与子类中 函数名相同 参数不同 无论父类中的同名函数是否含有virtual关键字 都是隐藏 与重写的区别 在父类和子类中 函数名相