亚洲精品中文免费|亚洲日韩中文字幕制服|久久精品亚洲免费|一本之道久久免费

      
      

            <dl id="hur0q"><div id="hur0q"></div></dl>

                C++之對待繼承得到的名字

                一.結(jié)論

                • 派生類中變量或者函數(shù)名字覆蓋基類的名字,是公有繼承所不希望的
                • 使用using聲明或者轉(zhuǎn)調(diào)函數(shù)可以使隱藏的函數(shù)名字或者變量名字可見

                二.詳細(xì)說明

                為了說明以上的結(jié)論,首先需要說明隱藏、覆蓋以及作用域等概念,接著舉例說明隱藏、覆蓋以及作用域等帶來的問題,最后以解決方法解決以上問題。

                2.1 隱藏、覆蓋和作用域

                作用域:從字面上理解,某事物起作用的地方,比如說白天太陽能夠照射的地方,能看到太陽,而照不到的地方就看不到太陽,能夠看到太陽的地方就是太陽的作用域。比較官方的定義如下:

                作用域:程序設(shè)計(jì)概念,通常來說,一段程序代碼中所用到的名字并不總是有效/可用的,而限定這個名字的可用性的代碼范圍就是這個名字的作用域 —百度百科

                隱藏:從字面上理解就是,因?yàn)槟呈挛锏牡絹?,一些事物被隱藏起來了,但是可以通過一些辦法讓它顯現(xiàn)出來,比如還以上面的例子,太陽照射不到的地方通過鏡子將陽關(guān)反射到被隱藏事物的地方(轉(zhuǎn)調(diào)),隱藏的事物亦可以看到太陽了。官方的定義:

                派生類將繼承的基類的同名的成員變量和成員方法隱藏起來,通過派生類只能訪問到自己的成員變量和成員方法。

                覆蓋: 從字面上理解,某些事物因?yàn)橛袥_突,在一些作用域下不能同時出現(xiàn),在某一片陽光下,要么只能出現(xiàn)事物A,要么只能出現(xiàn)事物B。

                覆蓋往往與繼承的類中有virtual修飾的函數(shù)有關(guān)。virtual修飾的函數(shù)為虛函數(shù)。而覆蓋就是基類中有virtual修飾的函數(shù),且在派生類中有與基類中的虛函數(shù)同名且同參數(shù)列表的函數(shù),那么派生類中的的該函數(shù)就會將基類中的函數(shù)覆蓋,調(diào)用時無法調(diào)用基類中的函數(shù)

                2.2.局部變量和全局變量選擇

                int val = 1; // global valuevoid main(){ double val = 2.5; // local value std::cout << val << std::endl; // out 2.5 std::cout << ::val << std::endl; // out 1}

                運(yùn)行結(jié)果:

                2.51

                當(dāng)編譯器在cout處輸出val時,將首先查找 TestFun 的作用域中是否有名字 val ,如果有則它將直接輸出這個變量的值,如果沒有則會向TestFun之外的地方查找val符號,找到則直接輸出。此處輸出2.5,局部的val變量覆蓋了全局的val變量。如果要想使用全局變量val,需要添加作用域::val。

                此處局部變量掩蓋全局變量,若想使用全局變量可添加作用域的形式使用

                2.3. 繼承時變量選擇

                有如下類繼承關(guān)系,基類中包含純虛函數(shù)、虛函數(shù)和非虛函數(shù),派生類公有繼承基類,包含基類中非虛函數(shù)的同名同參函數(shù)和獨(dú)有函數(shù),如下:

                class Base {private: int val; public: virtual void mFun1() = 0; virtual void mFun1(double) { std::cout << "Base mFun1 with param double" << std::endl; } virtual void mFun2() { std::cout << "Base mFun2" << std::endl; } void mFun3() { std::cout << "Base mFun3" << std::endl; } void mFun3(float) { std::cout << "Base mFun3 with param float" << std::endl; }};class Derived: public Base {public: virtual void mFun1() { std::cout << "Derieved mFun1" << std::endl; } void mFun3() { std::cout << "Derieved mFun3" << std::endl; mFun2(); } void mFun4() { std::cout << "Derieved mFun4" << std::endl; mFun3(); // mFun3(1.25); // no matching function }};

                1.在構(gòu)建派生類實(shí)例時,調(diào)用同名同參的非虛函數(shù)mFun3時,其搜索路徑是,先搜索mFun3內(nèi)部是否找到mFun2,如果沒有找到則在類Derived中查找mFun2,如果類內(nèi)有找到則繼續(xù)向上Base類中查找mFun2,如果沒有找到則繼續(xù)向本文件中查找mFun2等等。此處mFun2在Base類中找到,如下例子:

                int main() { Derived der; der.mFun3(); return 0;}

                運(yùn)行結(jié)果:

                Derieved mFun3Base mFun2

                2.在構(gòu)建派生類實(shí)例時,調(diào)用函數(shù)mFun4時,mFun4中現(xiàn)調(diào)用的mFun3只會調(diào)用派生類Derived中的mFun3,且無法調(diào)用帶參數(shù)的mFun3,否則編譯時會報no matching function錯誤,實(shí)例中調(diào)用帶參的mFun3一樣報錯,因?yàn)榕缮愔械暮瘮?shù)覆蓋了基類中的同名函數(shù)包括不同參數(shù),換句話說派生類中的同名函數(shù)覆蓋了了Base::mFun1和Base::mFun3。 如下例子:

                int main() { Derived der; der.mFun1(); // call Derived mFun1 der.mFun4(); // call Derived mFun4 // der.mFun3(1.25); // no matching function return 0;}

                運(yùn)行結(jié)果

                Derieved mFun4Derieved mFun3Base mFun2

                從上面的兩個例子中可以發(fā)現(xiàn)一個很明顯的問題,由于同名覆蓋的情況,導(dǎo)致在派生類中無法調(diào)用基類中同名不同參數(shù)的函數(shù), 以下就是一些解決辦法

                2.4 使用using聲明

                使用using 聲明可以將作用域從原先限定的地方拓展到聲明的地方,增加其使用范圍,例子如下:

                // Base基類同上class Derived: public Base {public: using Base::mFun3; virtual void mFun1() { std::cout << "Derieved mFun1" << std::endl; } void mFun3() { std::cout << "Derieved mFun3" << std::endl; mFun2(); } void mFun4() { std::cout << "Derieved mFun4" << std::endl; mFun3(); // mFun3(1.25); // no matching function }};

                使用Demo進(jìn)行測試:

                int main() { Derived der; der.mFun1(); // call Derived mFun1 der.mFun1(1.0); // call Base mFun1 der.mFun4(); // call Derived mFun4 der.mFun3(); // call Derived mFun3 der.mFun3(1.25); // call Base mFun3 return 0;}

                運(yùn)行結(jié)果:

                Derieved mFun1 // der.mFun1();Base mFun1 with param double // der.mFun1(1.0);Derieved mFun4 // der.mFun4();Derieved mFun3Base mFun2Derieved mFun3 // der.mFun3();Base mFun2Base mFun3 with param float // der.mFun3(1.25);

                從結(jié)果中可以看出使用using聲明將基類中的函數(shù)作用域拓展到了派生類中,在派生類中可以直接使用,假如派生類中只想繼承基類中不帶參數(shù)的函數(shù)該如何呢?這時使用using聲明可能會將帶參數(shù)的函數(shù)同時給引入進(jìn)來,而無法解決此類問題。此處可以通過轉(zhuǎn)調(diào)函數(shù)實(shí)現(xiàn),如下。

                2.5 使用轉(zhuǎn)掉函數(shù)

                私有繼承加上轉(zhuǎn)調(diào)函數(shù)可以完美解決using聲明不能解決的只繼承帶不參數(shù)的函數(shù),例子如下:

                // Base基類同上void Base::mFun1(){ std::cout << "Base mFun1" << std::endl;}class Derived: private Base {public: virtual void mFun1() { std::cout << "Derieved mFun1" << std::endl; Base::mFun1(); }};

                使用Demo進(jìn)行測試

                int main() { Derived der; der.mFun1(); // call Derived mFun1 // der.mFun1(1.0); // error no matching function return 0;}

                運(yùn)行結(jié)果:

                Derieved mFun1Base mFun1

                參考:

                1.Effective C++ Item33

                2.解析C++隱藏與覆蓋Oragen的博客-CSDN博客c++隱藏和覆蓋

                3.作用域_百度百科 (baidu.com)

                備注:

                歡迎大家多多指教,喜歡的大家可以點(diǎn)擊關(guān)注本賬號或者微信公眾號:軟件系統(tǒng)安全,后續(xù)將不定期更新C++相關(guān)的內(nèi)容

                鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
                用戶投稿
                上一篇 2022年8月8日 10:19
                下一篇 2022年8月8日 10:19

                相關(guān)推薦

                • 存儲過程語法(sql server存儲過程語法)

                  今天小編給各位分享存儲過程語法的知識,其中也會對sql server存儲過程語法進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧! oracle存儲過程基本語法…

                  2022年11月26日
                • 銳龍97900x參數(shù)規(guī)格跑分評測 銳龍97900x屬于什么檔次

                  銳龍9 7900X是銳龍7000系列處理器中性能頂尖的型號之一,它采用了這一代標(biāo)配的zen4架構(gòu)和5nm制程工藝,那么它具體的參數(shù)跑分如何,在電腦上世紀(jì)發(fā)揮怎么樣呢,下面就來看看銳…

                  2022年11月24日
                • 拉伊卜的名字的由來是什么(拉伊卜的名字的由來是什么)

                  近日有關(guān)卡塔爾世界杯吉祥物的名字大家也都十分的好奇。大家一直稱呼的餃子皮官方名字是拉伊卜,而對于拉伊卜這個名字的含義相信很多人還不懂。拉伊卜的名字的由來是什么?為什么要取名拉伊卜呢…

                  2022年11月23日
                • vivox90pro配置參數(shù)跑分詳情 vivox90pro是什么屏幕

                  vivox90pro參數(shù)配置詳情怎么樣?vivo手機(jī)在昨晚舉行了X90系列發(fā)布會,有普通款、pro款以及pro+款三個版本,那么vivox90pro具體配置怎么樣呢?下面就讓小編為…

                  2022年11月23日
                • vivox90參數(shù)配置詳情 vivox90處理器功耗跑分介紹

                  vivox90參數(shù)配置詳情怎么樣?vivo手機(jī)在昨晚舉行了X90系列發(fā)布會,有普通款、pro款以及pro+款三個版本,那么vivox90具體配置怎么樣呢?下面就讓小編為大家介紹一下…

                  2022年11月23日
                • 女子名叫“馬艷花仙波”被誤當(dāng)網(wǎng)名,當(dāng)事人:父母想要獨(dú)特不重名

                  極目新聞記者 余淵 李賢誠 為證實(shí)自己的名字是真的,北京一位名叫“馬艷花仙波”的女子,在社交平臺曬出了自己的身份證及戶口本。11月22日,當(dāng)事人馬女士告訴極目新聞記者,不少人曾質(zhì)疑…

                  2022年11月23日
                • 《寶可夢朱紫》索財(cái)靈硬幣有什么用?索財(cái)靈硬幣作用及獲取

                  寶可夢朱紫寶可夢索財(cái)靈是可以掉索財(cái)靈硬幣的,不少玩家不知道這個精靈掉落的硬幣有什么用,怎么獲取,小編這里給大家?guī)砹藢毧蓧糁熳纤髫?cái)靈硬幣作用及獲取,一起來看下文中具體介紹吧。 索財(cái)…

                  2022年11月22日
                • 新手開兩元店注意什么(開兩元店需要注意什么)

                  受疫情影響,一些小伙伴失業(yè)沒了生活來源,想要返鄉(xiāng)回家做點(diǎn)小生意,其中開兩元店是一個不錯的選擇,門檻低,投資成本低,作為新手有很多不懂,那么新手開兩元店注意什么?下面小編為大家?guī)硇隆?/p>

                  2022年11月22日
                • 寓意美好的家庭群名(2022最旺家庭群名字)

                  1、幸福之家 2、相親相愛一家人 3、we are伐木累 4、親人部落格 5、親親一家人 6、娘家人 7、親人一族 8、紅紅火火一家人 9、幸福之家 10、超幸福一家 11、歡樂家…

                  2022年11月22日
                • 又欲又撩的名字(好聽稀少的游戲ID)

                  好聽稀少的游戲ID大全 1、二字id 白夜、檸木、故夢、葬心、厭世、落羽、爛情、狂傲、蔸蔸、眾生、暮雨、冷巷、嘯鷹、狂爺、青橘、執(zhí)念、風(fēng)馳、撩漢、同歸、歌姬、珠珠、軟果、羅緯、子慕…

                  2022年11月21日

                聯(lián)系我們

                聯(lián)系郵箱:admin#wlmqw.com
                工作時間:周一至周五,10:30-18:30,節(jié)假日休息