C 基礎(五)虛函式 過載 覆蓋 隱藏

2021-06-21 10:40:09 字數 2932 閱讀 3621

虛函式總是跟多型聯絡在一起,引入虛函式可以使用基類指針對繼承類物件進行操作!

虛函式:繼承介面(函式名,引數,返回值),但是實現不繼承(函式體)

非虛函式:繼承介面,也繼承實現;

1)虛析構函式(當乙個類打算作為基類使用時候,其析構函式必須是虛函式)

建構函式可以為虛函式嗎?  不可以,在生成物件的時候,必須向編譯器明確指定要生成什麼型別的物件,因而不存在虛函式的問題;只有當物件已經存在,我用什麼介面去操作它的問題;

例子:class a

;class b: public  a

;int main()

這裡通過指標a去呼叫b類的析構函式,但是如果 ~a()不是虛析構函式,就不存在多型,就會去呼叫a中的析構函式,最後結果可能是b物件中的a成分被析構了,其他還殘留;所以當乙個類作為基類時候,其析構函式必須是虛函式,這樣防止出現析構不完全的情況;

2)當虛函式出現在構造、析構函式中時(即在建構函式中呼叫虛函式),函式退化為普通函式。為什麼? <>中條款

例子:**自<>中條例9)

class transaction  ;

transaction::transaction()

class buytransaction : public transaction  ;

這裡呼叫buytransaction的建構函式,因為buytransaction是繼承類所以先呼叫基類的建構函式,此時派生類獨有的那部分還未初始化,<>中這麼解釋:「這個物件內的buytransaction成分還未初始化,最安全的辦法是當他不存在,物件在derived成分還未初 始化時該物件不會成為乙個derived物件」所以transaction 的建構函式會呼叫基類的 logtransaction() const;而且此處是個純虛函式,會報錯

3)虛函式與覆蓋,過載,隱藏

過載首先出現在非繼承關係當中,當同乙個類中,兩個函式的引數不同,名字相同,返回值型別無所謂(函式返回值不作為過載的參考,因為函式呼叫時候不出現返回值);

注意兩個函式可以僅僅因為const與非const的差別來實現過載;

虛函式與覆蓋均出現在乙個繼承體系中,覆蓋針對的是普通函式,當父類子類中出現同名(相同返回值,相同引數,相同函式名)要求絕對一致

虛函式在父類子類中,首先父類中宣告該函式為virtual,那麼子類可以重新定義該函式的實現,這裡主要涉及多型,就是覆蓋的情況加上virtual,通過指標或者引用實現多型;

隱藏顯得簡單粗暴,在繼承類中只要出現於父類同名(只要求同樣的函式名/變數名,其他返回值,virtual  非virtual不管)的函式,則用物件呼叫同名函式時候,基類對應的同名函式、變數隱藏,如果要訪問其父類的同名成員應該明確使用  基類名::成員來訪問;

例子:class    a

;void process(int i,char c);           //過載,編譯期間即可確定該呼叫哪個函式

char  process(double d,int c);      //只要函式名相同,返回無所謂,引數不同

void process(int i);        

void process(int i)const;               // 此處相當於void process(const a *this,int i);

void process(consttint i);              //這裡僅僅因為const屬性不同即可實現過載

virtual int  foo(int, char);         

int foo2(){};

void foo3(int,int ){};

};class    b:   public a

;             //虛函式,這裡函式介面要嚴格一致(大部分編譯器要求返回值也要一致)

int   process();                 //隱藏基類函式  

int foo2(){};                            //  這裡不含虛屬性,會覆蓋

int foo3();               //會隱藏a類的foo3

};int main()

總結:

1)覆蓋與虛函式是一對兄弟,要求函式的返回值,函式名,引數嚴格一致,虛函式是覆蓋加上virtual的情況;

2) 隱藏是覆蓋的推廣,覆蓋是隱藏的特例,只要求函式名一樣,其他不管,在繼承體系中,子類的同名函式會將父類的同名函式隱藏;

3)當使用指標時候,指向基類的指標會根據實際物件的型別,選擇相應的虛函式執行,如果派生類沒有重新定義基類的虛函式,那麼依然執行基類的虛函式;

4)當不存在虛函式的情況下,使用基類的指標,不會下降到派生類中去搜尋函式;所以virtual屬性相當於告訴基類指標:當執行我時,請到相應物件中搜尋對應的虛函式;

5)純虛函式所在的類是抽象類,不能例項化,定義了純虛函式意味著這個函式只能為父類,其負責定義介面而不負責實現;

6)當使用物件來呼叫相應的函式時候,主要考慮的是對基類同名函式的隱藏(包括覆蓋),而不需要考慮多型;

7)注意構造析構函式中不能呼叫虛函式,當執行派生類的建構函式時候,先構造的是其基類成分,再執行派生類成分的構造,虛函式此時無意義;

8)c++是個細節非常多,非常複雜的語言;

參考:《effective c++》

C 函式 過載 覆蓋 隱藏

在c 的類中函式定義的時候會有 過載,覆蓋 也成為重寫 隱藏 也成為重定義 三種情況下面說說他們的區別,以及一些注意事項 學習c 中的類,主要有兩種,一種是用struct 關鍵字 定義的,預設情況下類中的成員是public屬性,而另一種使用class 關鍵字 定義的預設是private屬性的。子類在...

C 虛函式覆蓋 過載

cbase類處於作用域的外層,派生類的方法對於其將是不可見的,即隱藏的。而在派生類中,如果有過載函式時,基類函式將會被隱藏,否則基類函式就不被隱藏。includeusing namespace std 基類 class cbase virtual void jump void run int spe...

C 虛函式覆蓋 過載

在c 語言中,虛函式是非常重要的概念,虛函式是實現c 物件導向中多型性和繼承性的基石。而多型性和繼承性則是物件導向語言的精髓。掌握虛函式才算是真正掌握c 語言,而c 語言中虛函式的繼承覆蓋與函式過載有些類似,很多初學者搞不清他們之間的關係。首先要明確覆蓋 override 與過載 overload ...