C++函数重载、重写与重定义

2023-10-31

演示代码:

#include<iostream>
using namespace std;
class A {
public:
	virtual void Function(double i) {
		cout << "A: Function" << endl;
	}
	void Function1(int i, double d) {
		cout << "A: Function1" << endl;
	}
};
class B : public A {
public:
	//重载	和	重定义(隐藏)
	bool Function(int i) {
		cout << "B: Function(int)" << endl;
		return true;
	}
	//重写(也称为覆盖 override)
	void Function(double i) {					//若返回值不相同,则编译不通过
		cout << "B: Function(double)" << endl;
	}

	//重定义(隐藏)
	void Function1(double d) {
		cout << "B: Function1" << endl;
	}
};

int main() {
	B* bp = new B;
	bp->Function(4);				//B: Function(int)
	bp->Function(4.0);				//B : Function(double)
	bp->Function1(4.1);				//B: Function1
	A* bBp = bp;
	//bBp->Function1(4.1);				//编译出错,派生类重定义的函数Function1对该指针bp不可见
	//bp->Function1(1, 4.1);		//编译出错,因为基类函数被隐藏,无法调用
	return 0;
}

一、重载(overload)

在同一个作用域内,仅同名函数,但参数列(指参数的个数、类型或者顺序)必须不同,重载不关心函数返回类型。参数列表确定调用哪个函数。

1.匹配顺序
推荐相关文章:C++ 函数重载 指针类型匹配到bool类型

2.类的成员函数重载
除了拥有和一般全局函数重载的特性之外,const、volatile成员函数也构成重载
推荐相关文章:C++之const关键字的几种用法八、2
C++中volatile限定符

3.模板函数重载
函数匹配规则:
1).对于一个调用,其候选函数包括所有模版实参推断成功的函数模版实例(顶层const可忽略;对于非引用的形参,数组或函数指针转化到到指针)

2).可行函数(模版和非模版),按类型转换排序

3).如果恰有一个函数比其它都更匹配,则选择此函数,否则
a.如果只有一个非模版函数,选择他
b.没有非模版函数,选择更特例化的模版
c.否则,有歧义,编译错误

#include<iostream>
#include<cstring>

using namespace std;

//相对的泛化
template<class t>
inline bool LESS(const t& t1, const t& t2)//本质上可用于任何类型,包括指针类型。 
{
	cout << "general   ";
	return t1 < t2 ? 1 : 0;
}
template<class t>//指针类型的重载版 ,只能用于指针类型,所以比上一个更特例化。 
inline bool LESS(t* const t1, t* const t2)
{
	cout << "overload1  ";
	return *t1 < *t2 ? 1 : 0;
}
template<class t>//const指针类型的重载版 ,只能用于const指针类型,所以比上一个更特例化。 
inline bool LESS(const t* const t1, const t* const t2)
{
	cout << "overload2  ";
	return *t1 < *t2 ? 1 : 0;
}

bool LESS(const char* const t1, const char* const t2)//普通函数版本,优先级更高 
{
	cout << "function  ";
	return strcmp(t1, t2);
}

template<>
inline bool LESS<char>(const char &t1, const char &t2)//全特化 template<class t> t LESS(const t& t1, const t& t2)
{
	cout << "special_one   ";
	return t1 < t2 ? 1 : 0;
}
template<>
inline bool LESS<const int*>(const int* const &t1, const int* const &t2)//全特化 template<class t> t LESS(const t& t1, const t& t2)
{
	cout << "special_two   ";
	return *t1 < *t2 ? 1 : 0;
}


template<class T1, class T2>
decltype(auto) Add(const T1 &t1, const T2 &t2)
{
	cout << "Add1   ";
	return t1 + t2;
}

template<class T1>
decltype(auto) Add(const T1 &t1, const T1 &t2)				//特化
{
	cout << "Add2   ";
	return t1 + t2;
}

template<class T2>
decltype(auto) Add(const int &t1, const T2 &t2)				//偏特化
{
	cout << "Add3   ";
	return t1 + t2;
}

int main()
{
	int int1 = 10;
	int int2 = 20;
	int* pint1 = &int1;
	int* pint2 = &int2;
	const int cint1 = 40;
	const int cint2 = 30;
	const int* cpint1 = &cint1;
	const int* cpint2 = &cint2;
	char c1 = 'a';
	char c2 = 'z';
	const char* const cc1 = "abc";
	const char* const cc2 = "abc";
	const int* const cpintc1 = &cint1;
	const int* const cpintc2 = &cint2;

	cout << LESS(int1, int2) << endl;						//general
	cout << LESS(pint1, pint2) << endl;						//overload1
	cout << LESS(cpint1, cpint2) << endl;					//overload2
	cout << LESS(cc1, cc2) << endl;							//function
	cout << LESS("hi", "zzzz") << endl;						//function
	cout << LESS(c1, c2) << endl;							//special_one 
	cout << LESS(cpintc1, cpintc2) << endl;					//overload2

	cout << Add(std::string("mai"), 'n').c_str() << endl;	//Add1   main
	cout << Add(1.002, 'c') << endl;						//Add1	100.002
	cout << Add(1.002, 2121.2) << endl;						//Add2   2122.2
	cout << Add(74, true) << endl;							//Add3   75
	//cout << Add(10, 87) << endl;							//Add2和Add3匹配二义性
}

疑问cout << LESS(cpintc1, cpintc2) << endl; //overload2

三、重写(也称为覆盖 override)

派生类中存在重新定义的函数。其函数签名(函数名,参数列表)和返回值类型都必须与基类中被重写的函数一致,并且基类中被重写的函数必须有virtual修饰,只有函数体不同(花括号内)。
1、基类对象调用基类被重写的函数。
2、派生类对象调用派生类重写的函数(重写、覆盖了基类函数)。
3、指向基类对象的基类指针调用基类被重写的函数(不表现多态)。
4、指向派生类对象的基类指针调用派生类重写的函数(多态性)。

二、重定义(隐藏)
1、派生类的函数重定义基类与其同名的函数。若基类为非虚函数,只要函数名称相同(不管参数列表是否相同);若基类为虚函数,参数列表则需不同(参数列、返回值相同则为重写;参数列相同、返回值不同编译不通过),基类函数都会被重定义(隐藏)。
1、基类对象调用基类被重定义的函数。
2、派生类对象调用派生类重定义的函数(基类函数被隐藏)。
3、指向基类对象的基类指针调用基类被重定义的函数(不表现多态)。
4、指向派生类对象的基类指针调用基类重定义的函数(派生类重定义的函数对该指针不可见)。

如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810

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

C++函数重载、重写与重定义 的相关文章

随机推荐

  • [译]Time Series Forecasting with the Long Short-Term Memory Network in Python

    译 Time Series Forecasting with the Long Short Term Memory Network in Python 写在开头的话 这篇文章是 Dr Jason Brownlee 于2017 08 07发表
  • 用Python的Pandas和Matplotlib绘制股票KDJ指标线

    1 KDJ指标的计算过程 KDJ指标也叫随机指标 是由乔治 蓝恩博士 George Lane 最早提出的 该指标集中包含了强弱指标 动量概念和移动平均线的优点 可以用来衡量股价脱离正常价格范围的偏离程度 KDJ指标的计算过程是 首先获取指定
  • .有如下的4个/24地址块,试进行最大可能的聚合。212.56.132.0/24,212.56.133.0/24,212.56.134.0/24,212.56.135.0/24。

    有如下的4个 24地址块 试进行最大可能的聚合 212 56 132 0 24 212 56 133 0 24 212 56 134 0 24 212 56 135 0 24 由于四个地址块前两个字节都相同 只需将每个地址块的第三个字节转换
  • fedora系统更新时间

    先进行安装 yum install ntpdate 修改时区为上海 cp usr share zoneinfo Asia Shanghai etc localtime 之后运行两遍 ntpdate asia pool ntp org 使用c
  • 从Cortex-M33内核认识TrustZone

    欢迎大家关注STM32L5课程 本期我们会介绍STM32L5的内核 Cortex M33 它是ARM在MCU架构上增加了TrustZone这个安全扩展的一种内核实现 从这一期开始 我们进入技术部分的学习 L5快速入门 会由5期的介绍组成 会
  • git代码迁移后本地如何操作,如何变更为新的git仓库地址及重新配置用户名、密码

    git代码迁移后本地如何操作 如何变更为新的git仓库地址 答案是 直接切换git远程仓库地址即可 1 首先查看远程仓库的地址 git remote v 2 然后set url设置新的代码仓库地址 git remote set url or
  • .gitignore 文件和 .gitattributes 文件的使用

    每当想用 gitignore文件的时候 却发现已经push了不必要的文件 但如果你不慎在创建 gitignore文件之前就push了项目 那么即使你在 gitignore文件中写入新的过滤规则 这些规则也不会起作用 Git仍然会对所有文件进
  • cuda第一次计算耗时_FLUENT计算与GPU加速

    太长不看版本 结论如下 1 FLUENT中 GPU加速对于耦合求解器计算十分明显 3060ti能够提高计算效率约3倍 1080ti能够提高计算效率约2倍 2 FLUENT中 GPU加速对于分离式求解器效果不明显 这可能是由于网格数太少 GP
  • VirtualBox下Android-x86安装与基础配置

    虚拟机 Virtual Box 6 1 系统 android x86 64 8 1 r6 一 下载 Android x86 镜像 英文站 Android on x86 项目 中文站 安卓X86中文站 二 虚拟机配置 1 新建虚拟机 类型 L
  • 万能近似定理(universal approximation theorrm)

    神经网络的架构 architecture 指网络的整体结构 大多数神经网络被组织成称为层的单元组 然后将这些层布置成链式结构 其中每一层都是前一层的函数 在这种结构中 第一层由下式给出 第二层 第三层 以此类推 可以看出 每一层的主体都是线
  • Spring Framework与JDK版本对应关系

    最近在实践Spring项目时 发现无法通过注解的方式实现Bean容器管理 控制器报错信息为 Failed to read candidate component class 也就是注解扫描不了 在反复检查代码不存在问题后意识到可能是版本兼容
  • Java-主流框架—(10)Spring-微服务SpringBoot

    1 SpringBoot概述 SpringBoot提供了一种快速使用Spring的方式 基于约定优于配置的思想 可以让开发人员不必在配置与逻辑业务之间进行思维的切换 全身心的投入到逻辑业务的代码编写中 从而大大提高了开发的效率 Spring
  • 如何在mysql中创建学生信息表_数据库怎么创建学生信息表

    大家好 我是时间财富网智能客服时间君 上述问题将由我为大家进行解答 数据库创建学生信息表的方法是 1 新建表 单击数据库 studentDb 前图标 然后右键 表 文件包 单击 新建表 选项 进入 新建表 窗口 2 设定表标识字段id 填写
  • Vue项目安装core-js报错解决方案

    报错问题如下 出现这这种情况的多半是core js的版本不对 解决方案如下 亲测多次有效 1 安装cnpm npm install g cnpm registry https registry npm taobao org 2 查看cnpm
  • 浏览器页面后退,重新运行ajax

    问题描述 在浏览器页面后退时 也就是说你点击链接到一个页面 然后又点击后退按钮回到刚才的页面 结果发现jQuery的ajax GET请求不再执行了 解决方法 禁用ajax缓存 ajaxSetup cache false 吐槽 为了解决这个问
  • java中的String

    Java中的String类是一种复合数据类型 比较String类的是否相等也有2种办法 和equals 两种 String是一个系统定义的类 不是基本数据类型 有关字符串处理的方法非常多 有时候两个 一样 的字符串做相等的比较运算时会得到t
  • 华为OD机试真题-查找充电设备组合【2023Q1】【JAVA、Python、C++】

    题目描述 某个充电站 可提供n个充电设备 每个充电设备均有对应的输出功率 任意个充电设备组合的输出功率总和 均构成功率集合P的1个元素 功率集合P的最优元素 表示最接近充电站最大输出功率p max的元素 输入描述 输入为3行 第1行为充电设
  • 时序预测

    时序预测 MATLAB实现Bayes贝叶斯优化LSTM 长短期记忆神经网络 时间序列预测 预测效果一览
  • React - Websocket

    组件didMount调用 Store createWebSocket Math random Store url ws window backend server slice 7 apronMapWebsocket 这个要与后端提供的相同
  • C++函数重载、重写与重定义

    演示代码 include