C++ 中的 override 和 overload的区别
目录
1.Overload(重载)
2.override(重写)
3.override 和 overload 的根本区别
4.override 和 overload 的实际应用
5.override 和 overload 的常见误区
6.总结
1.Overload(重载)
-
定义:在同一个作用域内,可以声明几个功能类似的函数名相同的函数,但是这些函数的参数列表不同(参数个数不同、参数类型不同、参数顺序不同等)。这就是函数重载(Function Overloading)。
-
目的:主要是为了提供函数使用的灵活性,便于记忆和使用。
-
实现:通过改变函数的参数列表来实现。
-
示例:
class Example {
public: void print(int i) { std::cout << "Integer: " << i << std::endl; }void print(double d) { std::cout << "Double: " << d << std::endl; }void print(const std::string& s) { std::cout << "String: " << s << std::endl; }
};
在这个例子中,print 函数被重载了三次,分别接受 int、double 和 std::string 类型的参数。编译器根据传递的参数类型自动选择调用哪个函数。
C/C++中重载函数取地址的方法
2.override(重写)
-
定义:在派生类中,我们可以重写(Override)基类中的虚函数。这意呀着派生类提供了一个特定签名的成员函数,该函数与基类中的某个虚函数具有相同的名称、返回类型和参数列表。
-
目的:主要用于实现多态性。通过基类指针或引用,能够调用到派生类中的特定实现。
-
实现:通过在派生类的成员函数声明中使用
override关键字(C++11及以后)来显式地指出该函数重写了基类中的虚函数。如果不使用override关键字,编译器也会隐式地检查,但使用override可以提高代码的可读性和安全性。 -
示例:
class Base {
public: virtual void show() { std::cout << "Base class show" << std::endl; }
}; class Derived : public Base {
public: void show() override { // 使用override关键字明确表示该函数重写了基类中的虚函数 std::cout << "Derived class show" << std::endl; }
}; // 通过基类指针调用派生类的方法,体现了多态性
在上述代码中,Derived 类的 show() 函数使用了 override 关键字,明确表示它是对基类 Base 中虚函数的重写。编译器将检查函数签名是否与基类虚函数一致。
3.override 和 overload 的根本区别
概念上的区别
-
override(重写): 是针对类的继承关系中的虚函数,它允许子类重新定义基类的虚函数行为。函数签名必须与基类中的虚函数一致。
-
overload(重载): 是在同一作用域中定义多个同名函数,它们的参数列表不同,编译器通过参数的不同来区分这些函数。
作用域上的区别
-
override: 发生在继承体系中,子类继承自基类时,重写基类中的虚函数。
-
overload: 发生在同一类或同一作用域中,允许多个函数名相同但参数列表不同的函数并存。
编译器处理上的区别
-
override: 编译器会检查子类函数是否确实重写了基类的虚函数。如果签名不匹配,编译器将报错。
-
overload: 编译器会根据传递给函数的参数类型来选择正确的函数进行调用。
4.override 和 overload 的实际应用
override 的应用场景
override 常用于多态的实现,子类通过重写基类的虚函数来实现不同的行为,而不改变接口。这种方式允许我们利用面向对象的设计,实现代码的灵活性和可扩展性。
class Shape {public: virtual double area() const = 0; // 纯虚函数
};class Circle : public Shape {
public: Circle(double r) : radius(r) {} double area() const override { // 重写纯虚函数 return 3.14159 * radius * radius; }
private: double radius;
};
在这个例子中,Shape 类定义了一个纯虚函数 area(),而 Circle 类重写了该函数,提供了圆形的面积计算方法。
overload 的应用场景
函数重载经常用于需要同一个函数执行类似的操作,但处理不同类型的参数时。例如,打印函数可以根据输入的类型打印不同的信息。
class Logger {
public: void log(int i) { std::cout << "Logging int: " << i << std::endl; }void log(double d) { std::cout << "Logging double: " << d << std::endl; }void log(const std::string& s) { std::cout << "Logging string: " << s << std::endl; }
};
函数重载的应用场景极为广泛,从数学运算、输入输出到模板类函数,重载为代码的灵活性提供了极大支持。
5.override 和 overload 的常见误区
override 中的隐藏函数问题
如果我们在子类中定义了一个与基类中非虚函数同名但参数不同的函数,并没有使用 override,那么此时基类中的函数将会被“隐藏”,而不是重载。这可能导致意外的行为。
class Base {
public: virtual void func(int) { std::cout << "Base class show" << std::endl; }
}; class Derived : public Base {
public: void func(double) const { // 隐藏了基类的 func(int) std::cout << "Derived class show" << std::endl; }
};
在这个例子中,Derived 类定义了一个新的 func(double) 函数,这将隐藏基类的 func(int) 函数。在使用派生类时,如果传递 int 类型参数,调用的是 Base 的 func,而不是重载的版本。正确的做法是使用 using 来引入基类的重载版本。
overload 中的返回值问题
函数重载时,重载的区分条件是参数列表,而不是返回值类型。如果两个函数仅在返回值类型上不同,编译器会报错。
int func(int);
double func(int); // 错误,返回类型不同
6.总结
-
在重写基类虚函数时,始终使用
override关键字,确保编译器检查函数签名的正确性,避免意外的错误。 -
在进行函数重载时,确保参数列表的差异足以让编译器进行区分,同时保证函数的语义一致性。
-
如果需要在子类中使用基类的重载函数,使用
using关键字显式引入基类的函数,避免隐藏问题。
总之,在 C++ 中,理解 override 和 overload 的区别是掌握面向对象编程的重要一步。override 强调的是子类对基类虚函数的重写,是实现多态的基础。而 overload 则允许同一作用域内定义多个功能类似但参数不同的函数。两者各司其职,合理运用可以大大提升代码的灵活性和可读性。
相关文章:
C++ 中的 override 和 overload的区别
目录 1.Overload(重载) 2.override(重写) 3.override 和 overload 的根本区别 4.override 和 overload 的实际应用 5.override 和 overload 的常见误区 6.总结 1.Overload(重载) 定义:在同一个作用域内,可以声明几个功能类似的函数名相同的函数&am…...
spring boot3框架@Validated失效
项目中使用的springboot3.2.1,在使用Validated校验controller里参数时始终不生效;在网上查了相关资料,添加了spring-boot-starter-validation依赖但还是不行 经过层层调试,终于发现问题; springboot3添加Validated后校验的是 ja…...
UE5引擎工具链知识点
当我们提到“引擎工具链的开发”时,通常指的是为游戏开发或其他类型的软件开发创建一系列工具和技术栈的过程。这包括但不限于游戏引擎本身(如Unity或Unreal Engine),以及围绕这些引擎构建的各种工具和服务,比如用于构…...
Python的图像算术与逻辑运算详解
一.图像加法运算 图像加法运算主要有两种方法。第一种是调用Numpy库实现,目标图像像素为两张图像的像素之和;第二种是通过OpenCV调用add()函数实现。第二种方法的函数原型如下: dst add(src1, src2[, dst[, mask[, dtype]]]) – src1表示第…...
WSL 下的 CentOS 装 Docker
WSL 下的 CentOS 装 Docker 卸载旧版本安装前的准备工作1. 安装 yum-utils2. 添加阿里云的 yum 镜像仓库3. 快速生成 Yum 缓存 安装Docker启动docker运行 hello-world卸载 Docker 引擎参考资料 卸载旧版本 sudo yum remove docker \ docker-client \ docker-client-latest \ d…...
v0.dev快速开发
探索v0.dev:次世代开发者之利器 今之技艺日新月异,开发者之工具亦随之进步不辍。v0.dev者,新兴之开发者利器也,迅速引起众多开发者之瞩目。本文将引汝探究v0.dev之基本功能与优势,助汝速速上手,提升开发之…...
python之字符串
创建字符串 s "Hello, World!"常用字符串操作 获取字符串长度 length len(s) print(length) # 输出: 13字符串拼接 s1 "Hello" s2 "World" s3 s1 ", " s2 "!" print(s3) # 输出: Hello, World!重复字符串 s …...
算法打卡 Day28(回溯算法)-组合总数 + 组合总数 Ⅱ+ 电话号码的字母组合
文章目录 Leetcode 17-电话号码的字母组合题目描述解题思路 Leetcode 39-组合总数题目描述解题思路 Leetcode 216-组合总数 Ⅲ题目描述解题思路 Leetcode 17-电话号码的字母组合 题目描述 https://leetcode.cn/problems/letter-combinations-of-a-phone-number/description/ …...
【Hadoop|MapReduce篇】MapReduce概述
1. MapReduce定义 MapReduce是一个分布式运算程序的编程框架,是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上。 2. Map…...
设置Virtualbox虚拟机共享文件夹
由于工作环境的原因,选择Virtualbox的方式安装虚拟操作系统,常用的操作系统为ubuntu,不知道道友是否也曾遇到这样的问题,就是虚拟机和主机进行文件拖拽的时候,会因为手抖造成拖拽失败,虚拟机界面显示大个的…...
从零开始的机器学习之旅
尊敬的读者们,在这个快速发展的数字时代,机器学习无疑已经成为了科技领域的一颗璀璨明星。它如同一把打开未来之门的钥匙,让我们能够窥探到数据背后的无限可能。今天,我将带领大家开启一段从零开始的机器学习之旅,让我…...
开源还是封闭?人工智能的两难选择
这篇文章于 2024 年 7 月 29 日首次出现在 The New Stack 上。人工智能正处于软件行业的完美风暴中,现在马克扎克伯格 (Mark Zuckerberg) 正在呼吁开源 AI。 关于如何控制 AI 的三个强大观点正在发生碰撞: 1 . 所有 AI 都应该是开…...
Prometheus 服务监控
官网:https://prometheus.io Prometheus 是什么 Prometheus 是一个开源的系统监控和报警工具,专注于记录和存储时间序列数据(time-series data)。它最初由 SoundCloud 开发,并已成为 CNCF(云原生计算基金会…...
建模杂谈系列252 规则的串行改并行
说明 提到规则,还是需要看一眼RETE算法: Rete算法是一种用于高效处理基于规则的系统中的模式匹配问题的算法,广泛应用于专家系统、推理引擎和生产系统。它的设计目的是在大量规则和数据的组合中快速找到满足特定规则条件的模式。 Rete算法…...
0.ffmpeg面向对象oopc
因为查rtsp相关问题,接触了下ffmpeg源码,发现它和linux内核一样,虽然都是c写的,但是都是面向对象的思想,c的面向对象称之为oopc。 这让我想起来一件好玩的事,有些搞linux内核驱动的只会c的开发人员不知道l…...
KDD2024参会笔记-Day1
知乎想法:链接 听的第一场汇报:RAG Meeting LLMs 综述论文:https://arxiv.org/pdf/2405.06211 PPT:https://advanced-recommender-systems.github.io/RAG-Meets-LLMs/2024-KDD-RAG-Meets-LLM-tutorial-Part1.pdf 检索࿱…...
Java操作Elasticsearch的实用指南
Java操作Elasticsearch的实用指南 一、创建索引二、增删改查 一、创建索引 在ElasticSearch中索引相当于mysql中的表,mapping相当于表结构,所以第一步我们要先创建索引。 假设我们有一张文章表的数据需要同步到ElasticSearch,首先需要根据数据库表创建…...
数据库系统 第42节 数据库索引简介
数据库索引是数据库表中一个或多个列的数据结构,用于加快数据检索速度。除了基础的B-Tree索引,其他类型的索引针对特定的数据类型和查询模式提供了优化。以下是几种不同类型的索引及其使用场景的详细说明和示例代码。 1. 位图索引 (Bitmap Index) 位图…...
C++11 --- 智能指针
序言 在使用 C / C 进行编程时,许多场景都需要我们在堆上申请空间,堆内存的申请和释放都需要我们自己进行手动管理。这就存在容易造成堆内存泄露(忘记释放),二次释放,程序发生异常时内存泄露等问题…...
C#顺序万年历自写的求余函数与周位移算法
static int 返回月的天数(int 年, int 月){return (月 2 ?(((年 % 4 0 && 年 % 100 > 0) || 年 % 400 0) ? 29 : 28) :(((月 < 7 && 月 % 2 > 0) || (月 > 7 && 月 % 2 0)) ? 31 : 30));}static int 返回年总天数(int 年, int 标 …...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
