亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++中的重載、覆蓋、隱藏介紹

2020-01-26 15:07:58
字體:
來源:轉載
供稿:網友

前幾天面試時被問及C++中的覆蓋、隱藏,概念基本答不上來,只答了怎么用指針實現多態,也還有遺漏。最終不歡而散?;貋砗笤诰W上查找學習了一番,做了這個總結。其中部分文字借用了別人的博客,望不要見怪。

•概念

一、重載(overload)
指函數名相同,但是它的參數表列個數或順序,類型不同。但是不能靠返回類型來判斷。
(1)相同的范圍(在同一個作用域中) ;
(2)函數名字相同;
(3)參數不同;
(4)virtual 關鍵字可有可無。
(5)返回值可以不同;

二、重寫(也稱為覆蓋 override)
是指派生類重新定義基類的虛函數,特征是:
(1)不在同一個作用域(分別位于派生類與基類) ;
(2)函數名字相同;
(3)參數相同;
(4)基類函數必須有 virtual 關鍵字,不能有 static 。
(5)返回值相同(或是協變),否則報錯;<―-協變這個概念我也是第一次才知道…

(6)重寫函數的訪問修飾符可以不同。盡管 virtual 是 private 的,派生類中重寫改寫為 public,protected 也是可以的

三、重定義(也成隱藏)
(1)不在同一個作用域(分別位于派生類與基類) ;
(2)函數名字相同;
(3)返回值可以不同;
(4)參數不同。此時,不論有無 virtual 關鍵字,基類的函數將被隱藏(注意別與重載以及覆蓋混淆) 。
(5)參數相同,但是基類函數沒有 virtual關鍵字。此時,基類的函數被隱藏(注意別與覆蓋混淆) 。

•例子

#include <iostream>using namespace std;class SParent{public:  SParent( ){};  SParent( const SParent &p )  {    cout << "parent copy construct" << endl;  }  int add( int a,int b )  {    cout << "parent int add" << endl;    return a + b;  }  double add( double a,double b )  {    cout << "parent double add" << endl;    return a + b;  }  virtual int dec( int a,int b )  {    cout << "parent int dec" << endl;    return a - b;  }};class SChild : public SParent{public:  //using SParent::add;  float add( float a,float b )  {    cout << "child float add" << endl;    return a + b;  }  int dec(int a, int b)  {    cout << "child int dec" << endl;    return a - b;  }};int main(){  /* 測試重載 */  SParent parent;  parent.add( 3,5 );  parent.add( (double)3,(double)5 );  cout << endl;  /* 測試覆蓋 */  SChild *pchild = (SChild *)new SParent();/* 基類強轉為子類...危險...,用dynamic_cast轉換也不行 */  pchild->dec( 10,3 );  SParent *pparent = new SChild();  pparent->dec( 11,3 );  cout << endl;  /* 測試隱藏 */  SChild child;  child.add( (int)3,(int)5 );  cout << endl;  /* 測試函數表 */  ((SParent *)NULL)->add( 4,6 );  ((SChild *)NULL)->add( 4,6 );  int a = 0;  ((SChild *)&a)->add( 4,6 );   cout << endl;  /* 測試函數地址 */  ((SParent)child).add( (int)4,(int)8 );  child.SParent::add( 3,5 );  return 0;}

輸出結果:

parent int addparent double addparent int decchild int decchild float addparent int addchild float addchild float addparent copy constructparent int addparent int add按 <RETURN> 來關閉窗口...

•理解
int SParent::add(int a,int b)與double SParent::add( double a,double b )是重載

int SParent::add(int a,int b)與double SParent::add( double a,double b )都被子類SChild中的float SChild::add( float a,float b )隱藏

int SParent::dec( int a,int b )被子類SChild中的int SChild::dec( int a,int b )覆蓋

•測試

1.重載測試,簡單易懂,略過。
2.覆蓋測試。dec函數在基類、子類中同名同參,為虛函數,故稱覆蓋。

SChild *pchild = (SChild *)new SParent()創建的是一個基類對象,其函數表應該為

SParent *pparent = new SChild();創建一個子類對象,其函數表應該為

由上面的函數表可見,當發生覆蓋時,子類的函數名會把基類的同名函數覆蓋(這也就是為什么叫覆蓋的原因吧)。這樣我們可以利用一個指向子類的基類指針實現多態。但重點只有一
個,就是函數表里到底指向誰(不管這個指針經過轉換后是什么類型的).故輸出分別為父類、子類。這是一個運行時多態。

3.隱藏測試

int SParent::add(int a,int b)與double SParent::add( double a,double b )都被子類SChild中的float SChild::add( float a,float b )覆蓋,是因為他們同名,而且在不同的作用域中(基類、子類作用域是不同的)。child.add( (int)3,(int)5 );這行代碼中,編譯器在子類中查找add函數,只找到了一個(基類的add(int a,int b)會被編譯根據隱藏規則略過),再根據隱式類型轉換發現該函數適用。如果無法隱式轉換,則編譯不過。隱藏的原因:防止隱式類型轉換造成錯誤。比如int也是可以轉換成char的,假如基類有一函數add(char a,char b),子類也有一函數add(double a,double b)。程序員想著在子類隱式把int轉換為double,但編譯器可能調的是基類的。這也防止了一些庫或封裝好的基類對程序員造成困擾。

  像上面的代碼,如果你確實需要基類的函數,可以用using SParent:add。則把基類的add函數域擴大到了子類,構成重載。

4.函數表測試

上面我們說到函數表,這個是在編譯時定好的,程序運行時加載到內存中。這意味著我們可以直接通過地址去調用函數。所以((SChild *)NULL)->add( 4,6 );這種代碼也是能運行通過的。網上還有人通過計算直接取到了函數表的地址直接調用了。但這種代碼不安全不規范不說,還有個更大的問題。當成員函數里需要調用成員變量時,通過這種假的對象指針肯定找不到成員變量表,直接訪問了非法內存。

5.函數地址測試

有了隱藏、覆蓋,哪么我們要怎么調用被隱藏、覆蓋的函數呢。下面有兩種方法:

    ((SParent)child).add( (int)4,(int)8 );
    child.SParent::add( 3,5 );

第一種是比較低效的方法。事實上它是通過拷貝構造函數生成一個臨時的基類變量去調用基類的add函數。
第二種通過::指定域去訪問。這種方法是編譯器根據域直接找到了基類的函數地址,跟函數表沒有多大關系。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品免费久久久久影院| 国产精品免费一区二区三区都可以| 亚洲天堂成人在线| 日本19禁啪啪免费观看www| 亚洲综合视频1区| 国产精品青青在线观看爽香蕉| 色妞在线综合亚洲欧美| 国产亚洲欧洲高清| 精品毛片网大全| 日本免费久久高清视频| 日韩av男人的天堂| 中文字幕日韩综合av| 91在线视频成人| 日韩精品极品毛片系列视频| 久久久久久久久中文字幕| 国产脚交av在线一区二区| 91日韩在线视频| 精品福利视频导航| 91在线视频九色| 久久久国产精品免费| 欧美老女人性视频| 亚洲精品电影网站| 黑人巨大精品欧美一区二区三区| 国产91在线高潮白浆在线观看| 国产精品成久久久久三级| www.日韩不卡电影av| 久久久久久久久久婷婷| 色妞在线综合亚洲欧美| 亚洲天堂2020| 91av视频在线免费观看| 亚洲精品国产精品久久清纯直播| 国产精品尤物福利片在线观看| 日韩一区视频在线| 日本a级片电影一区二区| 日韩福利视频在线观看| 亚洲一区二区免费在线| 日韩精品极品在线观看| 国产成人福利夜色影视| 国产成人+综合亚洲+天堂| 最新国产成人av网站网址麻豆| 久久资源免费视频| 国内精品模特av私拍在线观看| 亚洲欧洲在线免费| 成人看片人aa| 精品美女国产在线| 久久久这里只有精品视频| 久久综合免费视频影院| 亚洲精品中文字幕女同| 欧美人在线视频| 91精品国产91久久久| 亚洲精品天天看| 伊人久久精品视频| 91精品国产91久久| 91国产精品91| 国产久一一精品| 欧美精品在线网站| 国产精品视频色| 欧美精品一区二区免费| 在线视频精品一| 91美女片黄在线观看游戏| 日韩电影第一页| 亚洲精品永久免费精品| 久久理论片午夜琪琪电影网| 欧美中文字幕第一页| 久久影视电视剧免费网站清宫辞电视| 亚洲韩国欧洲国产日产av| 久久久国产一区二区三区| 欧美精品制服第一页| 亚洲激情在线观看| 性夜试看影院91社区| 国产不卡av在线| 日韩在线视频免费观看高清中文| 91在线视频精品| 91午夜理伦私人影院| 一区二区欧美日韩视频| 国产精品久久久久久久久免费看| 日韩欧美国产骚| 亚洲福利视频在线| 国产精品xxxxx| 国产成人a亚洲精品| 日本国产欧美一区二区三区| 亚洲第一在线视频| 91麻豆国产语对白在线观看| 国产中文字幕91| 欧美性猛交xxx| 国产一区二区三区视频在线观看| 亚洲桃花岛网站| 欧美日韩国产中字| 欧美日韩免费网站| 欧美日韩在线视频观看| 日韩高清电影好看的电视剧电影| 国模精品一区二区三区色天香| 欧美日韩加勒比精品一区| 久久久久久久久久久91| 久久精品成人欧美大片| 亚洲午夜性刺激影院| 国产精品久久久久av| 久久精品精品电影网| 九九久久久久久久久激情| xxxxxxxxx欧美| 欧美国产精品日韩| 亚洲精品成a人在线观看| 亚洲在线观看视频网站| 久久人人看视频| 91精品视频在线| 亚州av一区二区| 精品女同一区二区三区在线播放| 色噜噜狠狠狠综合曰曰曰| 欧美一级淫片videoshd| 91麻豆国产语对白在线观看| 亚洲人成毛片在线播放| 国产丝袜一区二区三区| 欧美性jizz18性欧美| 国产91精品黑色丝袜高跟鞋| 视频在线一区二区| 国产精品一区二区久久国产| 国产成人高清激情视频在线观看| 久久天天躁日日躁| 狠狠躁夜夜躁人人躁婷婷91| 国产aaa精品| 91精品国产综合久久香蕉| 欧美激情网友自拍| 亚洲美女视频网站| 少妇精69xxtheporn| 97视频免费在线观看| 久久久免费观看| 久久五月天色综合| 欧美大片在线看| 国产在线播放不卡| 国产精品久久综合av爱欲tv| 性日韩欧美在线视频| 亚洲天堂av在线免费观看| 最近2019中文字幕一页二页| 日韩在线观看网址| 97久久久免费福利网址| 成人福利在线观看| 超碰91人人草人人干| 日韩中文字幕免费看| 久久色免费在线视频| 欧美电影在线观看| 日韩电影中文字幕| 爽爽爽爽爽爽爽成人免费观看| 久久久久女教师免费一区| 亚洲视频网站在线观看| 国产精品视频精品| 日韩电影免费在线观看| 亚洲天堂男人的天堂| 日韩经典中文字幕| 日韩在线视频播放| 国内精品小视频| 亚洲sss综合天堂久久| 91久久国产综合久久91精品网站| 日本久久久久亚洲中字幕| 最近2019中文字幕一页二页| 亚洲国产精品久久91精品| 亚洲精品福利资源站| 91高潮在线观看| 亚洲国产美女久久久久| 欧美夜福利tv在线| 国产69精品99久久久久久宅男| 亚洲成人久久电影| 日韩精品在线第一页| 欧美在线精品免播放器视频| 久久久久久久久国产精品|