一文詳解C++子類函數(shù)為什么不能重載父類函數(shù)
先說(shuō)結(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)
說(shuō)明float類型的a向上轉(zhuǎn)型為double,調(diào)用了子類的函數(shù),重載沒(méi)有在子類和基類間發(fā)生。這里如果類型轉(zhuǎn)換不能發(fā)生,將不能通過(guò)編譯。
而b.foo(a)的輸出為:
Base :: foo(float)
這說(shuō)明重載在單個(gè)類內(nèi)部進(jìn)行。
如果實(shí)在想在子類中調(diào)用父類的函數(shù),對(duì)于下面的例子二(不能編譯通過(guò)):
class A { public: void a() {} }; class B : public A { public: void a(int) {} }; int main() { B b; b.a(); }
如果需要上面的函數(shù)可以編譯通過(guò),我們可以這樣做:
- 在class B 內(nèi)部加上using A::a
- 調(diào)用時(shí)使用b.A::a(),不推薦這樣做
當(dāng)然,問(wèn)題的關(guān)鍵是為什么C++的設(shè)計(jì)者這么設(shè)計(jì),從技術(shù)實(shí)現(xiàn)來(lái)說(shuō),訪問(wèn)基類函數(shù)來(lái)進(jìn)行名字查找,實(shí)現(xiàn)跨類重載沒(méi)有太大的難度。但是從實(shí)際用戶意圖來(lái)說(shuō),像上面B中添加void a(int)函數(shù)的目的就是為了重新實(shí)現(xiàn)A的接口,并隱藏原來(lái)的接口;當(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ì)的原因。
到此這篇關(guān)于一文詳解C++子類函數(shù)為什么不能重載父類函數(shù)的文章就介紹到這了,更多相關(guān)C++子類函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
由static_cast和dynamic_cast到C++對(duì)象占用內(nèi)存的全面分析
下面小編就為大家?guī)?lái)一篇由static_cast和dynamic_cast到C++對(duì)象占用內(nèi)存的全面分析。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01Linux?C/C++實(shí)現(xiàn)網(wǎng)絡(luò)流量分析工具
網(wǎng)絡(luò)流量分析的原理基于對(duì)數(shù)據(jù)包的捕獲、解析和統(tǒng)計(jì)分析,通過(guò)對(duì)網(wǎng)絡(luò)流量的細(xì)致觀察和分析,幫助管理員了解和優(yōu)化網(wǎng)絡(luò)的性能,本文將通過(guò)C++實(shí)現(xiàn)網(wǎng)絡(luò)流量分析工具,有需要的可以參考下2023-10-10C++使用easyX庫(kù)實(shí)現(xiàn)三星環(huán)繞效果流程詳解
EasyX是針對(duì)C/C++的圖形庫(kù),可以幫助使用C/C++語(yǔ)言的程序員快速上手圖形和游戲編程。這篇文章主要介紹了C++使用easyX庫(kù)實(shí)現(xiàn)三星環(huán)繞效果,需要的可以參考一下2022-10-10最短時(shí)間學(xué)會(huì)基于C++實(shí)現(xiàn)DFS深度優(yōu)先搜索
常見(jiàn)使用深度優(yōu)先搜索(DFS)以及廣度優(yōu)先搜索(BFS)這兩種搜索,今天我們就來(lái)講講什么是深度優(yōu)先搜索,感興趣的可以了解一下2021-08-08利用C++實(shí)現(xiàn)從std::string類型到bool型的轉(zhuǎn)換
利用C++實(shí)現(xiàn)從std::string類型到bool型的轉(zhuǎn)換。需要的朋友可以過(guò)來(lái)參考下。希望對(duì)大家有所幫助2013-10-10C語(yǔ)言實(shí)現(xiàn)自動(dòng)存取款機(jī)模擬系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)自動(dòng)存取款機(jī)模擬系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05