当前位置: 首页 > news >正文

继承下的缺省参数值和访问说明符

前言

本文将介绍 C++ 继承体系下,函数缺省参数的绑定和函数访问说明符的绑定。这些奇怪的问题实际上不应在我们的代码中出现,但它们能帮助我们理解 C++ 的动态绑定和静态绑定,也能帮助我们更好的通过面试。

缺省参数值

先来看一段代码:

class A {
public:virtual void fun(char ch = 'A') {cout << ch << endl;}
};class B : public A {
public:virtual void fun(char ch = 'B') {cout << ch << ch << endl;}
};int main() {A* pa = new B;pa->fun();return 0;
}

上述代码的运行结果是什么?是 A 还是 BB 呢?

很遗憾,都不是,代码的运行结果是 AA。

解释

发生这种现象的原因是:virtual 函数是动态绑定,而缺省参数是静态绑定。静态绑定又名前期绑定,在编译时确定;动态绑定又名后期绑定,在运行时确定。

cppreference 对这行为的解释:虚函数的覆盖函数不会从基类定义获得默认实参,而在进行虚函数调用时,默认实参根据对象的静态类型确定。

静态类型与动态类型:

A* pa = new B;	// 静态类型是 A*,动态类型是 B*
B* pb = new B;	// 静态类型是 B*,动态类型是 B*

对象的静态类型就是我们在代码中所写的类型,而动态类型则是指「目前所指对象的类型」。

这样也就能解释上述代码了,因为 a 的静态类型是 A*,在编译时,参数的缺省值绑定的是 ‘A’。而虚函数是动态绑定,取决于动态类型,绑定的是 B 类中重写后的函数实现。

为什么 C++ 采用了如此奇怪的方式运行?

答案在于运行期效率。如果缺省参数是动态绑定,编译器就必须有某种方法在运行期为 virtual 函数决定适当的参数缺省值。这比目前实行的「在编译期决定」的机制更慢而且更复杂。

访问说明符

下面来看一段更加奇怪的代码:

class A {
public:virtual void fun() {cout << "A" << endl;}
};class B : public A {
private:virtual void fun() {cout << "B" << endl;}
};int main() {A* pa = new B;pa->fun();B b;b.fun();return 0;
}

上述代码的运行结果是什么?

a->fun() 正确,并打印出 B;b.fun() 报编译错误,无法访问 private 成员。

解释

发生这种现象与访问说明符作用时间有关。

cppreference 对访问说明符的说明:

每个类成员(静态、非静态、函数、类型等)的名字都具有与其关联的「成员访问」。在程序的任何位置使用成员的名字时都会检查其访问,而且如果它不满足访问规则,那么程序不能编译。成员访问检查是对任何给定语言构造进行解释之后的最后一步。此规则的目的是使得以 public 替换任何 private 时始终不会改变程序的行为。

对虚函数的名字的访问规则,在调用点使用(用于代表调用该成员函数的对象的)表达式的类型进行检查,忽略最终覆盖函数的访问。

从上述表述,可以得出两点:

  1. 访问说明符只在编译时有效,当代码加载到内存后,没有任何访问说明符上的区别
  2. 虚函数的访问说明符,由调用该虚函数的对象的静态类型决定

这也就能解释上述代码了:

pa 的静态类型为 A*,A::fun() 是 public 的,可以调用。b 的静态类型是 B,B::fun() 是 private 的,不能调用。

相关文章:

继承下的缺省参数值和访问说明符

前言 本文将介绍 C 继承体系下&#xff0c;函数缺省参数的绑定和函数访问说明符的绑定。这些奇怪的问题实际上不应在我们的代码中出现&#xff0c;但它们能帮助我们理解 C 的动态绑定和静态绑定&#xff0c;也能帮助我们更好的通过面试。 缺省参数值 先来看一段代码&#xf…...

Spring核心模块—— BeanFactoryPostProcessorBeanPostProcessor(后处理器)

后置处理器前言Spring的后处理器BeanFactoryPostProcessor&#xff08;工厂后处理器&#xff09;执行节点作用基本信息经典场景子接口——BeanDefinitiRegistryPostProcessor基本介绍用途具体原理例子——注册BeanDefinition使用Spring的BeanFactoryPostProcessor扩展点完成自定…...

产品新人如何培养产品思维?

什么是产品思维&#xff1f;其实很难定义&#xff0c;不同人有不同的定义。有的人定义为以用户为中心打磨一个完美体验的产品&#xff1b;有的定义为从需求调研到需求上线各个步骤需要思考的点&#xff0c;等等。本文想讨论的产品思维是&#xff1a;怎么去发现问题&#xff0c;…...

「兔了个兔」CSS如此之美,看我如何实现可爱兔兔LOADING页面(万字详解附源码)

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读&#xff0c;同时任汉硕云&#xff08;广东&#xff09;科技有限公司ABAP开发顾问。在学习工作中&#xff0c;我通常使用偏后…...

【Java】阻塞队列 BlcokingQueue 原理、与等待唤醒机制condition/await/singal的关系、多线程安全总结

在实习过程中使用阻塞队列对while sleep 轮询机制进行了改造&#xff0c;提升了发送接收的效率&#xff0c;这里做一点点总结。 自从Java 1.5之后&#xff0c;在java.util.concurrent包下提供了若干个阻塞队列&#xff0c;BlcokingQueue继承了Queue接口&#xff0c;是线程安全…...

【水下图像增强】Enhancing Underwater Imagery using Generative Adversarial Networks

原始题目Enhancing Underwater Imagery using Generative Adversarial Networks中文名称使用 GAN 增强水下图像发表时间2018年1月11日平台ICRA 2018来源University of Minnesota, Minneapolis MN文章链接https://arxiv.org/abs/1801.04011开源代码官方&#xff1a;https://gith…...

Maven专题总结—详细版

第一章 为什么使用Maven 获取jar包 使用Maven之前&#xff0c;自行在网络中下载jar包&#xff0c;效率较低。如【谷歌、百度、CSDN…】使用Maven之后&#xff0c;统一在一个地址下载资源jar包【阿里云镜像服务器等…】 添加jar包 使用Maven之前&#xff0c;将jar复制到项目工程…...

华为OD机试真题Java实现【字符串加密】真题+解题思路+代码(20222023)

字符串加密 题目 给你一串未加密的字符串str, 通过对字符串的每一个字母进行改变来实现加密, 加密方式是在每一个字母str[i]偏移特定数组元素a[i]的量, 数组a前三位已经赋值:a[0]=1,a[1]=2,a[2]=4。 当i>=3时,数组元素a[i]=a[i-1]+a[i-2]+a[i-3], 例如:原文 abcde …...

「Python 基础」函数与高阶函数

文章目录1. 函数调用函数定义函数函数的参数递归函数2. 高阶函数map/reducefiltersorted3. 函数式编程返回函数匿名函数装饰器偏函数1. 函数 函数是一种重复代码的抽象方式&#xff0c;Python 内建支持的一种封装&#xff1b; 调用函数 调用一个函数&#xff0c;需要知道函数…...

DIV内容滚动,文字符滚动标签marquee兼容稳定不卡

marquee(文字滚动)标签 marquee简介 <marquee>标签,是成对出现的标签,首标签<marquee>和尾标签</marquee>之间的内容就是滚动内容。 <marquee>标签的属性主要有behavior、bgcolor、direction、width、height、hspace、vspace、loop、scrollamount、scr…...

SpringBoot_第五章(Web和原理分析)

目录 1&#xff1a;静态资源 1.1&#xff1a;静态资源访问 1.2&#xff1a;静态资源源码解析-到WebMvcAutoConfiguration 2&#xff1a;Rest请求绑定&#xff08;设置put和delete&#xff09; 2.1&#xff1a;代码实例 2.2&#xff1a;源码分析到-WebMvcAutoConfiguratio…...

4-2 Linux进程和内存概念

文章目录前言进程状态进程优先级内存模型进程内存关系前言 进程是一个其中运行着一个或多个线程的地址空间和这些线程所需要的系统资源。一般来说&#xff0c;Linux系统会在进程之间共享程序代码和系统函数库&#xff0c;所以在任何时刻内存中都只有代码的一份拷贝。 进程状态…...

【微信小程序】计算器案例

&#x1f3c6;今日学习目标&#xff1a;第二十一期——计算器案例 ✨个人主页&#xff1a;颜颜yan_的个人主页 ⏰预计时间&#xff1a;30分钟 &#x1f389;专栏系列&#xff1a;我的第一个微信小程序 计算器前言实现效果实现步骤wxmlwxssjs数字按钮事件处理函数计算按钮处理事…...

408 计算机基础复试笔记 —— 更新中

计算机组成原理 计算机系统概述 问题一、冯诺依曼机基本思想 存储程序&#xff1a;程序和数据都存储在同一个内存中&#xff0c;计算机可以根据指令集执行存储在内存中的程序。这使得程序具有高度灵活性和可重用性。指令流水线&#xff1a;将指令分成若干阶段&#xff0c;每…...

找出最大数-课后程序(Python程序开发案例教程-黑马程序员编著-第二章-课后作业)

实例6&#xff1a;找出最大数 “脑力大乱斗”休闲益智游戏的关卡中&#xff0c;有一个题目是找出最大数。本实例要求编写程序&#xff0c;实现从输入的任意三个数中找出最大数的功能。 实例分析 对于3个数比较大小&#xff0c;我们可以首先先对两个数的大小进行比较&#xff…...

Java——N叉树的层序遍历

题目链接 leetcode在线oj题——N叉树的层序遍历 题目描述 给定一个 N 叉树&#xff0c;返回其节点值的层序遍历。&#xff08;即从左到右&#xff0c;逐层遍历&#xff09;。 树的序列化输入是用层序遍历&#xff0c;每组子节点都由 null 值分隔&#xff08;参见示例&…...

【Kubernetes】第十八篇 - k8s 服务发现简介

一&#xff0c;前言 上一篇&#xff0c;介绍了阿里云 ECS 服务器重启后的环境修复&#xff1b; 本篇&#xff0c;介绍 k8s 服务发现&#xff1b; 二&#xff0c;服务发现简介 当 A服务依赖了 B服务&#xff0c;而 B服务的IP和端口未知&#xff08;或相对不固定&#xff09;&…...

Codeforces Round 856 (Div. 2) 最好ak的div2

最近几场的div2 E都是一个思路啊&#xff0c;代码大差不差的&#xff0c;感觉随便ak啊。 A. Prefix and Suffix Array 题意 给你前n−1n-1n−1个字符串前缀和后n−1n-1n−1个字符串后缀&#xff0c;判断原字符串是否是回文串 思路 相同长度的判断是否是对称的即可。 代码 B C…...

最新JVM技术: GraalVM,让你一文了解它的方方面面

1. 什么是GraalVM? GraalVM是一种开源的虚拟机平台,由Oracle公司开发。它支持多种编程语言,包括Java、JavaScript、Python、Ruby、R、C++等,旨在提高应用程序的性能和扩展性。 GraalVM通过提供即时编译器(Just-in-Time Compiler,JIT)和Ahead-of-Time(AOT)编译器来提…...

MySQL索引失效的场景

1.like 以%开头&#xff0c;索引无效&#xff1b;当like前缀没有%&#xff0c;后缀有%时&#xff0c;索引有效。 2.数据库表数据量过小 如果表的数据量非常小&#xff0c;则MySQL可能不会使用索引&#xff0c;因为它认为全表扫描的代价更小。 3.or语句前后没有同时使用索引 …...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...