欧美大屁股bbbbxxxx,狼人大香伊蕉国产www亚洲,男ji大巴进入女人的视频小说,男人把ji大巴放进女人免费视频,免费情侣作爱视频

歡迎來到入門教程網(wǎng)!

C語言

當(dāng)前位置:主頁 > 軟件編程 > C語言 >

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

來源:本站原創(chuàng)|時間:2020-01-10|欄目: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();/* 基類強(qiáng)轉(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ù)域擴(kuò)大到了子類,構(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)系。

上一篇:C++動態(tài)規(guī)劃之最長公子序列實例

欄    目:C語言

下一篇:Linux線程同步之信號C語言實例

本文標(biāo)題:C++中的重載、覆蓋、隱藏介紹

本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/3105.html

網(wǎng)頁制作CMS教程網(wǎng)絡(luò)編程軟件編程腳本語言數(shù)據(jù)庫服務(wù)器

如果侵犯了您的權(quán)利,請與我們聯(lián)系,我們將在24小時內(nèi)進(jìn)行處理、任何非本站因素導(dǎo)致的法律后果,本站均不負(fù)任何責(zé)任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權(quán)所有