一次基类类型对象无法被传递问题的分析
看下面一段代码:
// proj2.cpp
#include <iostream>
using namespace std;
class CharShape {
public:CharShape(char ch) : _ch(ch) {};virtual void Show() = 0;
protected:char _ch; // 组成图形的字符
};
class Triangle : public CharShape {
public:Triangle(char ch, int r) : CharShape(ch), _rows(r) {}void Show();
private:int _rows; // 行数
};
class Rectangle : public CharShape {
public:Rectangle(char ch, int r, int c) :CharShape(ch), _rows(r), _cols(c) {}void Show();
private:int _rows, _cols; // 行数和列数
};
void Triangle::Show() // 输出字符组成的三角形
{for (int i = 1; i <= _rows; i++) {for (int j = 1; j <= i; j++)cout << _ch;cout << endl;}
}void Rectangle::Show() // 输出字符组成的矩形
{for (int i = 1; i <= _rows; i++) {for (int j = 1; j <= _cols; j++)cout << _ch;cout << endl;}
}//********Error******** 为fun函数添加形参
void fun(CharShape cs) { cs.Show(); }
int main()
{Triangle tri('*', 4);Rectangle rect('#', 3, 8);fun(tri);fun(rect);return 0;
}
void fun(CharShape cs) { cs.Show(); } 这行代码无法正常工作,CharShape 类型的对象无法被传递。
那么如何正确地通过函数传递 CharShape 类型的对象。首先,让我们分析为什么 void fun(CharShape cs) { cs.Show(); } 不工作,而 void fun(CharShape& cs) { cs.Show(); } 可以。
问题分析
值传递 (void fun(CharShape cs) { cs.Show(); })
当你使用值传递时,你实际上是在传递 CharShape 对象的一个副本到 fun 函数中。因为 CharShape 类包含一个纯虚函数 Show(),它是一个抽象类,不能被直接实例化。因此,当你试图传递 Triangle 或 Rectangle 的对象(它们都是 CharShape 的派生类)到 fun 函数时,会发生切片(slicing)现象,即只复制了基类 CharShape 的部分(不包括派生类的任何成员),并且因为基类是一个抽象类,所以无法直接创建这个副本。
此外,即使 CharShape 不是抽象的,传递基类对象副本到 fun 函数也不会调用派生类的 Show() 方法,因为函数内部处理的是基类对象,它只知道基类的 Show() 方法(如果存在的话)。
引用传递 (void fun(CharShape& cs) { cs.Show(); })
当你使用引用传递时,你实际上是在传递对象的引用(而不是副本)到 fun 函数中。因此,函数内部操作的是原始对象,而不是它的副本。这意味着你可以传递 Triangle 或 Rectangle 的对象到 fun 函数,并且因为 Show() 方法在派生类中被重写(overridden),所以当你调用 cs.Show(); 时,会调用相应派生类的 Show() 方法。
解决方案
使用引用传递(即 void fun(CharShape& cs) { cs.Show(); })是正确的做法,因为这样可以确保你操作的是原始对象,并且可以正确地调用派生类的 Show() 方法。
另外,注意 fun 函数现在接受一个对 CharShape 的引用,这意味着你不能传递一个临时对象(比如 fun(Triangle(‘*’, 4)); 这样的直接构造调用)给 fun,因为临时对象不能被引用。但在你的 main 函数中,你已经正确地创建了 Triangle 和 Rectangle 的对象,并将它们的引用传递给了 fun 函数。
相关文章:
一次基类类型对象无法被传递问题的分析
看下面一段代码: // proj2.cpp #include <iostream> using namespace std; class CharShape { public:CharShape(char ch) : _ch(ch) {};virtual void Show() 0; protected:char _ch; // 组成图形的字符 }; class Triangle : public CharShape { public:Tr…...
windows设置Redis服务后台自启动
问题 在日常开发过程中,redis是我们常用的缓存工具,但是由于redis对于Linux系统进行开发的,在Linux系统里可以通过修改redis.conf从而从而实现后台启动。 daemonize no 改成 daemonize yes 但是在window上如何也进行后台运行呢,…...
掌握Linux常用命令,扫平面试需求障碍
cd 切换目录。 > cd ../ #切换到父级目录 > cd /tmp # 切换到/tmp目录 > cd ~ # 切换到当前用户的家目录 ls命令 查看文件与目录的命令,list 的缩写。 > ls -l #列出长数据串,包含文件的属性与权限数据等 > ls -a #列出隐藏…...
c语言之文件打开模式
在c语言中,文件打开模式如下 r读模式: 允许对文件读取信息。若文件不存在,则会报错 w写模式: 允许向文件写入信息,若文件不存在,则创建一个文件 #include<stdio.h>int main() {FILE *fp;int i;char ay;fpfo…...
与禹老师学前端vue3学习汇总
24.5.15: 创建Vue3工程 1.确定自己电脑有没有nodejs环境,在cmd中输入node,如果出现Node.js的版本号说明已经有这个环境了,否则搜索Node.js安装 2.先在D盘创建一个文件夹Vue3_Study,然后在这个空文件夹中右键选择终端…...
Linux网络编程——HTTP协议的理解与运用
目录 前言 一、认识URL 二、认识HTTP样例 三、HTTP的报头内容 1.url 2. Content-Type 3.Method 方法 1.GET方法 2.POST方法 4、状态码 5.cookie和session 前言 我们知道,协议就是一种约定,客户端与服务端统一的用这种约定进行传输数据。我们…...
RestTemplate接口请求发送json、form数据格式以及处理接口错误状态码400 null
在使用RestTemplate发送HTTP请求时,你可以通过不同的方式发送JSON或表单数据(application/x-www-form-urlencoded)。同时,处理接口错误状态码(如400)和返回null的情况也是很重要的。以下是一些示例代码&…...
《Python编程从入门到实践》day29
# 昨日知识点回顾 修改折线图文字和线条粗细 矫正图形 使用内置格式 # 今日知识点学习 15.2.4 使用scatter()绘制散点图并设置样式 import matplotlib.pyplot as plt import matplotlib matplotlib.use(TkAgg)plt.style.use(seaborn-v0_8) # 使用内置格式 fig, ax plt.subpl…...
UIKit之图片浏览器
功能需求 实现一个图片浏览器,点击左右按钮可以切换背景图,且更新背景图对应的索引页和图片描述内容。 分析: 实现一个UIView的子类即可,该子类包含多个按钮。 实现步骤: 使用OC语言,故创建cocoa Touch类…...
如何查看SNMP设备的OID
什么是OID和MIB OID OID 代表对象标识符。 OID 唯一地标识 MIB 层次结构中的托管对象。 这可以被描述为一棵树,其级别由不同的组织分配。MIB MIB(管理信息基)提供数字化OID到可读文本的映射。 使用MIB Browser扫描OID 我的设备是一台UPS SN…...
什么?你设计接口什么都不考虑?
如果让你设计一个接口,你会考虑哪些问题? 1.接口参数校验 接口的入参和返回值都需要进行校验。 入参是否不能为空,入参的长度限制是多少,入参的格式限制,如邮箱格式限制 返回值是否为空,如果为空的时候是…...
2024年3月 青少年等级考试机器人理论真题二级
202403 青少年等级考试机器人理论真题二级 第 1 题 一个机器小车,用左右两个电机分别控制左右车轮,左侧电机转速是100rpm,右侧电机转速是50rpm,则此机器小车?( ) A:原地右转 B&am…...
C语言学习【printf函数和scanf函数】
C语言学习【printf函数和scanf函数】 printf()函数和scanf()函数可以让用户与程序交流,是输入/输出函数 printf()函数 请求printf()函数打印数据的指令要与待打印数据的类型相匹配。例如,打印整数时使用%d,打印字符时使用%c。这些符号被称…...
shell正则表达式
sort命令 以行为单位对文件内容进行排序,也可以根据不同的数据类型来排序 比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。 sort 对行内容进行升序排序 XXX | sort 选项 sort 选项 文件 常用选项&#x…...
react组件渲染性能优化之函数组件-useCallback使用
useCallback主要就是对函数进行缓存,useCallBack这个Hooks主要是解决React.memo不能缓存事件的问题 useCallBack(fn, dependencies) :fn想要缓存的函数,dependencies有关是否更新 fn 的所有响应式值的一个列表 比如:UseCallBackOptimize组件…...
【C++】:string类的基本使用
目录 引言一,string类对象的常见构造二,string类对象的容量操作三,string类对象的访问及遍历操作四,string类对象的修改操作五,string类非成员函数六,整形与字符串的转换 引言 string 就是我们常说的"…...
多线程的代码案例
目录 单例模式 饿汉模式 懒汉模式 阻塞队列 生产者消费者模型意义: 阻塞队列使用方法 实现阻塞队列 阻塞队列实现生产者消费者模型 定时器 实现简单的定时器 工厂模式 线程池 为啥呢? 从池子里面取 比 创建线程 效率更高 线程池的创建 怎么填坑 ThreadPoolExec…...
什么是Java中的设计模式?请列举几种常见的设计模式
一、引言 在软件开发中,设计模式是解决特定设计问题的最佳实践或通用解决方案。Java作为一种广泛使用的编程语言,其设计模式在软件设计和架构中起着至关重要的作用。设计模式不仅提高了代码的可读性和可维护性,还使得代码更加灵活和可扩展。…...
绘制奇迹:Processing中的动态图形与动画
🚀 欢迎回到Processing的世界,你的艺术编程航程刚刚开始。在我们的入门篇中,你已经学会了如何用Processing绘制基本的静态图形。现在,让我们一起探索Processing强大的动态图形和动画功能,释放你的创造力,走…...
Django视图Views
Views视图 HttpRequest 和HttpResponse Django中的视图主要用来接受web请求,并做出响应。视图的本质就是一个Python中的函数视图的响应分为两大类 1)以Json数据形式返回(JsonResponse) 2)以网页的形式返回 2.1)重定向到另一个网页 (HttpRe…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
书籍“之“字形打印矩阵(8)0609
题目 给定一个矩阵matrix,按照"之"字形的方式打印这个矩阵,例如: 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为:1,…...
Win系统权限提升篇UAC绕过DLL劫持未引号路径可控服务全检项目
应用场景: 1、常规某个机器被钓鱼后门攻击后,我们需要做更高权限操作或权限维持等。 2、内网域中某个机器被钓鱼后门攻击后,我们需要对后续内网域做安全测试。 #Win10&11-BypassUAC自动提权-MSF&UACME 为了远程执行目标的exe或者b…...
虚幻基础:角色旋转
能帮到你的话,就给个赞吧 😘 文章目录 移动组件使用控制器所需旋转:组件 使用 控制器旋转将旋转朝向运动:组件 使用 移动方向旋转 控制器旋转和移动旋转 缺点移动旋转:必须移动才能旋转,不移动不旋转控制器…...
二叉树-144.二叉树的前序遍历-力扣(LeetCode)
一、题目解析 对于递归方法的前序遍历十分简单,但对于一位合格的程序猿而言,需要掌握将递归转化为非递归的能力,毕竟递归调用的时候会调用大量的栈帧,存在栈溢出风险。 二、算法原理 递归调用本质是系统建立栈帧,而非…...
