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

一次基类类型对象无法被传递问题的分析

看下面一段代码:


// 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 函数。

相关文章:

一次基类类型对象无法被传递问题的分析

看下面一段代码&#xff1a; // 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服务后台自启动

问题 在日常开发过程中&#xff0c;redis是我们常用的缓存工具&#xff0c;但是由于redis对于Linux系统进行开发的&#xff0c;在Linux系统里可以通过修改redis.conf从而从而实现后台启动。 daemonize no 改成 daemonize yes 但是在window上如何也进行后台运行呢&#xff0c…...

掌握Linux常用命令,扫平面试需求障碍

cd 切换目录。 > cd ../ #切换到父级目录 > cd /tmp # 切换到/tmp目录 > cd ~ # 切换到当前用户的家目录 ls命令 查看文件与目录的命令&#xff0c;list 的缩写。 > ls -l #列出长数据串&#xff0c;包含文件的属性与权限数据等 > ls -a #列出隐藏…...

c语言之文件打开模式

在c语言中&#xff0c;文件打开模式如下 r读模式: 允许对文件读取信息。若文件不存在&#xff0c;则会报错 w写模式&#xff1a; 允许向文件写入信息&#xff0c;若文件不存在&#xff0c;则创建一个文件 #include<stdio.h>int main() {FILE *fp;int i;char ay;fpfo…...

与禹老师学前端vue3学习汇总

24.5.15&#xff1a; 创建Vue3工程 1.确定自己电脑有没有nodejs环境&#xff0c;在cmd中输入node&#xff0c;如果出现Node.js的版本号说明已经有这个环境了&#xff0c;否则搜索Node.js安装 2.先在D盘创建一个文件夹Vue3_Study&#xff0c;然后在这个空文件夹中右键选择终端…...

Linux网络编程——HTTP协议的理解与运用

目录 前言 一、认识URL 二、认识HTTP样例 三、HTTP的报头内容 1.url 2. Content-Type 3.Method 方法 1.GET方法 2.POST方法 4、状态码 5.cookie和session 前言 我们知道&#xff0c;协议就是一种约定&#xff0c;客户端与服务端统一的用这种约定进行传输数据。我们…...

RestTemplate接口请求发送json、form数据格式以及处理接口错误状态码400 null

在使用RestTemplate发送HTTP请求时&#xff0c;你可以通过不同的方式发送JSON或表单数据&#xff08;application/x-www-form-urlencoded&#xff09;。同时&#xff0c;处理接口错误状态码&#xff08;如400&#xff09;和返回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之图片浏览器

功能需求 实现一个图片浏览器&#xff0c;点击左右按钮可以切换背景图&#xff0c;且更新背景图对应的索引页和图片描述内容。 分析&#xff1a; 实现一个UIView的子类即可&#xff0c;该子类包含多个按钮。 实现步骤&#xff1a; 使用OC语言&#xff0c;故创建cocoa Touch类…...

如何查看SNMP设备的OID

什么是OID和MIB OID OID 代表对象标识符。 OID 唯一地标识 MIB 层次结构中的托管对象。 这可以被描述为一棵树&#xff0c;其级别由不同的组织分配。MIB MIB&#xff08;管理信息基&#xff09;提供数字化OID到可读文本的映射。 使用MIB Browser扫描OID 我的设备是一台UPS SN…...

什么?你设计接口什么都不考虑?

如果让你设计一个接口&#xff0c;你会考虑哪些问题&#xff1f; 1.接口参数校验 接口的入参和返回值都需要进行校验。 入参是否不能为空&#xff0c;入参的长度限制是多少&#xff0c;入参的格式限制&#xff0c;如邮箱格式限制 返回值是否为空&#xff0c;如果为空的时候是…...

2024年3月 青少年等级考试机器人理论真题二级

202403 青少年等级考试机器人理论真题二级 第 1 题 一个机器小车&#xff0c;用左右两个电机分别控制左右车轮&#xff0c;左侧电机转速是100rpm&#xff0c;右侧电机转速是50rpm&#xff0c;则此机器小车&#xff1f;&#xff08; &#xff09; A&#xff1a;原地右转 B&am…...

C语言学习【printf函数和scanf函数】

C语言学习【printf函数和scanf函数】 printf()函数和scanf()函数可以让用户与程序交流&#xff0c;是输入/输出函数 printf()函数 请求printf()函数打印数据的指令要与待打印数据的类型相匹配。例如&#xff0c;打印整数时使用%d&#xff0c;打印字符时使用%c。这些符号被称…...

shell正则表达式

sort命令 以行为单位对文件内容进行排序&#xff0c;也可以根据不同的数据类型来排序 比较原则是从首字符向后&#xff0c;依次按ASCII码值进行比较&#xff0c;最后将他们按升序输出。 sort 对行内容进行升序排序 XXX | sort 选项 sort 选项 文件 常用选项&#x…...

react组件渲染性能优化之函数组件-useCallback使用

useCallback主要就是对函数进行缓存,useCallBack这个Hooks主要是解决React.memo不能缓存事件的问题 useCallBack(fn, dependencies) &#xff1a;fn想要缓存的函数&#xff0c;dependencies有关是否更新 fn 的所有响应式值的一个列表 比如&#xff1a;UseCallBackOptimize组件…...

【C++】:string类的基本使用

目录 引言一&#xff0c;string类对象的常见构造二&#xff0c;string类对象的容量操作三&#xff0c;string类对象的访问及遍历操作四&#xff0c;string类对象的修改操作五&#xff0c;string类非成员函数六&#xff0c;整形与字符串的转换 引言 string 就是我们常说的"…...

多线程的代码案例

目录 单例模式 饿汉模式 懒汉模式 阻塞队列 生产者消费者模型意义: 阻塞队列使用方法 实现阻塞队列 阻塞队列实现生产者消费者模型 定时器 实现简单的定时器 工厂模式 线程池 为啥呢? 从池子里面取 比 创建线程 效率更高 线程池的创建 怎么填坑 ThreadPoolExec…...

什么是Java中的设计模式?请列举几种常见的设计模式

一、引言 在软件开发中&#xff0c;设计模式是解决特定设计问题的最佳实践或通用解决方案。Java作为一种广泛使用的编程语言&#xff0c;其设计模式在软件设计和架构中起着至关重要的作用。设计模式不仅提高了代码的可读性和可维护性&#xff0c;还使得代码更加灵活和可扩展。…...

绘制奇迹:Processing中的动态图形与动画

&#x1f680; 欢迎回到Processing的世界&#xff0c;你的艺术编程航程刚刚开始。在我们的入门篇中&#xff0c;你已经学会了如何用Processing绘制基本的静态图形。现在&#xff0c;让我们一起探索Processing强大的动态图形和动画功能&#xff0c;释放你的创造力&#xff0c;走…...

Django视图Views

Views视图 HttpRequest 和HttpResponse Django中的视图主要用来接受web请求&#xff0c;并做出响应。视图的本质就是一个Python中的函数视图的响应分为两大类 1)以Json数据形式返回(JsonResponse) 2)以网页的形式返回 2.1)重定向到另一个网页 (HttpRe…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇

根据 QYResearch 发布的市场报告显示&#xff0c;全球市场规模预计在 2031 年达到 9848 万美元&#xff0c;2025 - 2031 年期间年复合增长率&#xff08;CAGR&#xff09;为 3.7%。在竞争格局上&#xff0c;市场集中度较高&#xff0c;2024 年全球前十强厂商占据约 74.0% 的市场…...