網(wǎng)站首頁 編程語言 正文
先說結(jié)論:
子類成員函數(shù)的函數(shù)名和基類一樣,但是函數(shù)聲明與基類不一樣的時(shí)候,不會(huì)和基類函數(shù)構(gòu)成重載,而是會(huì)隱藏基類函數(shù)
簡(jiǎn)要回顧下C++中的基本概念:
- 重寫(override): 基類函數(shù)帶virtual,子類函數(shù)聲明和基類完全一樣,實(shí)現(xiàn)不一樣重
- 載(overload): 同一個(gè)類中,函數(shù)名一樣,函數(shù)參數(shù)類型,個(gè)數(shù),順序等不一樣的構(gòu)成重載
- 隱藏(hide): 子類函數(shù)名和基類一樣,但是函數(shù)聲明與基類不一樣,就會(huì)對(duì)基類的函數(shù)進(jìn)行隱藏
那么,子類函數(shù)名和基類一樣,但是函數(shù)聲明與基類不一樣的時(shí)候,為什么不能重載基類函數(shù)呢?
先看
例子一:
#include <stdio.h>
class Base {
public:
virtual void foo(float a) {
printf(" Base :: foo(float) \n");
};
virtual void foo(double a) {
printf(" Base :: foo(double) \n");
};
};
class Derived : public Base {
public:
virtual void foo(double a) {
printf(" Derived :: foo(double) \n");
};
};
int main() {
Derived d;
float a = 3.0f;
d.foo(a);
Base b;
b.foo(a);
}
如果重載可以發(fā)生在子類和基類之間,函數(shù)調(diào)用d.foo(a)的最佳匹配應(yīng)該是Base::foo(float a),而實(shí)際輸出是
Derived :: foo(double)
說明float類型的a向上轉(zhuǎn)型為double,調(diào)用了子類的函數(shù),重載沒有在子類和基類間發(fā)生。這里如果類型轉(zhuǎn)換不能發(fā)生,將不能通過編譯。
而b.foo(a)的輸出為:
Base :: foo(float)?
這說明重載在單個(gè)類內(nèi)部進(jìn)行。
如果實(shí)在想在子類中調(diào)用父類的函數(shù),對(duì)于下面的例子二(不能編譯通過):
class A
{
public:
void a() {}
};
class B : public A
{
public:
void a(int) {}
};
int main()
{
B b;
b.a();
}
如果需要上面的函數(shù)可以編譯通過,我們可以這樣做:
- 在class B 內(nèi)部加上using A::a
- 調(diào)用時(shí)使用b.A::a(),不推薦這樣做
當(dāng)然,問題的關(guān)鍵是為什么C++的設(shè)計(jì)者這么設(shè)計(jì),從技術(shù)實(shí)現(xiàn)來說,訪問基類函數(shù)來進(jìn)行名字查找,實(shí)現(xiàn)跨類重載沒有太大的難度。但是從實(shí)際用戶意圖來說,像上面B中添加void a(int)函數(shù)的目的就是為了重新實(shí)現(xiàn)A的接口,并隱藏原來的接口;當(dāng)然,如果用戶不想隱藏,可以加上using A::a。
另外,對(duì)于例子一,如果實(shí)現(xiàn)了跨類重載,那么d.foo(a)將也會(huì)調(diào)用到基類的函數(shù),盡管float可以轉(zhuǎn)型到float, 將很容易引起混淆。
順應(yīng)用戶意圖和避免不必要的混淆,這可能就是C++設(shè)計(jì)者這么設(shè)計(jì)的原因。
原文鏈接:https://blog.csdn.net/ithiker/article/details/108763166
相關(guān)推薦
- 2022-06-22 為Visual?Studio2019添加Git組件_實(shí)用技巧
- 2022-07-03 el-upload上傳組件的動(dòng)態(tài)添加;el-upload動(dòng)態(tài)上傳文件;el-upload區(qū)分文件是哪
- 2023-01-21 Python?sklearn中的K-Means聚類使用方法淺析_python
- 2023-07-16 SVN版本回退 revert to this revision
- 2023-10-10 函數(shù)柯里化的簡(jiǎn)單實(shí)現(xiàn)和應(yīng)用
- 2022-07-12 Python根據(jù)交集、并集對(duì)比兩個(gè)文件
- 2022-11-22 Kotlin?List與Set和Map實(shí)例講解_Android
- 2022-06-19 詳解Rainbond內(nèi)置ServiceMesh微服務(wù)架構(gòu)_云其它
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支