最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2021年10月01日 22:54:43   投稿:mdxy-dxy  
這篇文章主要介紹了C++中的重載、覆蓋、隱藏介紹,需要的朋友可以參考下

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

概念

一、重載(overload)

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

二、重寫(也稱為覆蓋 override)

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

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

三、重定義(也成隱藏)

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

例子

#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();/* 基類強轉(zhuǎn)為子類...危險...,用dynamic_cast轉(zhuǎn)換也不行 */
  pchild->dec( 10,3 );
  SParent *pparent = new SChild();
  pparent->dec( 11,3 );
  cout << endl;
  /* 測試隱藏 */
  SChild child;
  child.add( (int)3,(int)5 );
  cout << endl;
  /* 測試函數(shù)表 */
  ((SParent *)NULL)->add( 4,6 );
  ((SChild *)NULL)->add( 4,6 );
  int a = 0;
  ((SChild *)&a)->add( 4,6 );
   cout << endl;
  /* 測試函數(shù)地址 */
  ((SParent)child).add( (int)4,(int)8 );
  child.SParent::add( 3,5 );

  return 0;
}

輸出結(jié)果:

parent int add
parent double add

parent int dec
child int dec

child float add

parent int add
child float add
child float add

parent copy construct
parent int add
parent int add
按 <RETURN> 來關(guān)閉窗口...

理解

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函數(shù)在基類、子類中同名同參,為虛函數(shù),故稱覆蓋。

SChild *pchild = (SChild *)new SParent()創(chuàng)建的是一個基類對象,其函數(shù)表應(yīng)該為

SParent *pparent = new SChild();創(chuàng)建一個子類對象,其函數(shù)表應(yīng)該為

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

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函數(shù),只找到了一個(基類的add(int a,int b)會被編譯根據(jù)隱藏規(guī)則略過),再根據(jù)隱式類型轉(zhuǎn)換發(fā)現(xiàn)該函數(shù)適用。如果無法隱式轉(zhuǎn)換,則編譯不過。隱藏的原因:防止隱式類型轉(zhuǎn)換造成錯誤。比如int也是可以轉(zhuǎn)換成char的,假如基類有一函數(shù)add(char a,char b),子類也有一函數(shù)add(double a,double b)。程序員想著在子類隱式把int轉(zhuǎn)換為double,但編譯器可能調(diào)的是基類的。這也防止了一些庫或封裝好的基類對程序員造成困擾。

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

4.函數(shù)表測試

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

5.函數(shù)地址測試

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

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

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

相關(guān)文章

  • 引用參數(shù)和傳值參數(shù)的區(qū)別深入解析

    引用參數(shù)和傳值參數(shù)的區(qū)別深入解析

    以下是對引用參數(shù)和傳值參數(shù)的區(qū)別進行了詳細的分析介紹,需要的朋友可以過來參考下
    2013-07-07
  • 利用C語言實現(xiàn)三子棋(井字棋)小游戲

    利用C語言實現(xiàn)三子棋(井字棋)小游戲

    這篇文章主要為大家詳細介紹了利用C語言實現(xiàn)三子棋小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C++11的for循環(huán)的新用法(推薦)

    C++11的for循環(huán)的新用法(推薦)

    C++11這次的更新帶來了令很多C++程序員期待已久的for range循環(huán),每次看到j(luò)avascript, lua里的for range,心想要是C++能有多好,心里別提多酸了。這次C++11不負眾望,再也不用羨慕別家人的for range了。下面看下C++11的for循環(huán)的新用法
    2021-11-11
  • 詳解C語言內(nèi)核中的鏈表與結(jié)構(gòu)體

    詳解C語言內(nèi)核中的鏈表與結(jié)構(gòu)體

    Windows內(nèi)核中是無法使用vector容器等數(shù)據(jù)結(jié)構(gòu)的,當(dāng)我們需要保存一個結(jié)構(gòu)體數(shù)組時,就需要使用內(nèi)核中提供的專用鏈表結(jié)構(gòu)。本文分享了幾個內(nèi)核中使用鏈表存儲多個結(jié)構(gòu)體的通用案例,希望對你有所幫助
    2022-09-09
  • C語言如何實現(xiàn)圖片文件的復(fù)制

    C語言如何實現(xiàn)圖片文件的復(fù)制

    這篇文章主要為大家詳細介紹了C語言中實現(xiàn)圖片文件的復(fù)制的相關(guān)方法,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • 深入理解C/C++混合編程

    深入理解C/C++混合編程

    本篇文章是對C/C++混合編程進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • 基于QT制作一個倒計時軟件

    基于QT制作一個倒計時軟件

    這篇文章主要為大家詳細介紹了如何基于QT制作一個簡單的倒計時軟件,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • 深入理解約瑟夫環(huán)的數(shù)學(xué)優(yōu)化方法

    深入理解約瑟夫環(huán)的數(shù)學(xué)優(yōu)化方法

    本篇文章是對約瑟夫環(huán)的數(shù)學(xué)優(yōu)化方法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • 帶你深度走入C語言取整以及4種函數(shù)

    帶你深度走入C語言取整以及4種函數(shù)

    大家都知道取整這回事,但是對于取整只有單一的認識,下面這篇文章主要給大家介紹了關(guān)于C語言取整以及4種函數(shù)的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • C++超詳細講解拷貝構(gòu)造函數(shù)

    C++超詳細講解拷貝構(gòu)造函數(shù)

    我們經(jīng)常會用一個變量去初始化一個同類型的變量,那么對于自定義的類型也應(yīng)該有類似的操作,那么創(chuàng)建對象時如何使用一個已經(jīng)存在的對象去創(chuàng)建另一個與之相同的對象呢
    2022-06-06

最新評論

阜康市| 盐源县| 景德镇市| 阳西县| 望城县| 噶尔县| 大兴区| 江门市| 建昌县| 阜新市| 周宁县| 湄潭县| 福海县| 米泉市| 桦川县| 依兰县| 波密县| 平山县| 波密县| 东台市| 依安县| 扶余县| 翼城县| 进贤县| 临沂市| 精河县| 洱源县| 灌阳县| 临漳县| 遂昌县| 台山市| 当涂县| 秭归县| 宁乡县| 渑池县| 南平市| 商洛市| 竹北市| 乌审旗| 壤塘县| 屯留县|