您好,登錄后才能下訂單哦!
函數重載、函數隱藏、函數覆蓋
函數重載只會發生在同作用域中(或同一個類中),函數名稱相同,但參數類型或參數個數不同。 函數重載不能通過函數的返回類型來區分,因為在函數返回之前我們并不知道函數的返回類型。
函數隱藏和函數覆蓋只會發生在基類和派生類之間。
函數隱藏是指派生類中函數與基類中的函數同名,但是這個函數在基類中并沒有被定義為虛函數,這種情況就是函數的隱藏。
所謂隱藏是指使用常規的調用方法,派生類對象訪問這個函數時,會優先訪問派生類中的這個函數,基類中的這個函數對派生類對象來說是隱藏起來的。 但是隱藏并不意味這不存在或完全不可訪問。通過 b->Base::func()訪問基類中被隱藏的函數。
函數覆蓋特指由基類中定義的虛函數引發的一種多態現象。在某基類中聲明為 virtual 并在一個或多個派生類中被重新定義的成員函數,用法格式為:virtual 函數返回類型 函數名(參數表) {函數體};實現多態性,通過指向派生類的基類指針或引用,訪問派生類中同名覆蓋成員函數。
函數覆蓋的條件:
函數覆蓋(多態)實現了一種基類訪問(不同)派生類的方法。我們把它稱為基類的逆襲。
基類指針和派生類指針之間的轉換
1. 基類指針指向基類對象、派生類指針指向派生類對象
這種情況是常用的,只需要通過對應類的指針直接調用對應類的功能就可以了。
#include<iostream> using namespace std; class Father{ public: void print() { printf("Father's function!"); } }; class Son:public Father { public: void print() { printf("Son's function!"); } }; int main() { Father f1; Son s1; Father* f = &f1; Son* s = &s1; f->print(); cout<<endl<<endl; s->print(); }
2. 基類指針指向派生類對象
這種情況是允許的,通過定義一個基類指針和一個派生類對象,把基類指針指向派生類對象,但是需要注意,通常情況這時的指針調用的是基類的成員函數。分四種情況:
一、 函數在基類和派生類中都存在
這時通過“指向派生類對象的基類指針”調用成員函數,調用的是基類的成員函數。
Father f1;
Son s1;
Father* f = &s1;
f->print(); //調用的是基類成員函數
二、函數在基類中不存在,在派生類中存在
由于調用的還是基類中的成員函數,試圖通過基類指針調用派生類才有的成員函數,則編譯器會報錯。
error C2039: “xxx”: 不是“Father”的成員
三、 將基類指針強制轉換為派生類指針
這種是向下的強制類型轉換,轉換之后“指向派生類的基類指針”就可以訪問派生類的成員函數:
Son s1;
Father* f = &s1;
Son *s = (Son*)f;
s->print1(); //調用派生類成員函數
但是這種強制轉換操作是一種潛在的危險操作。
四、基類中存在虛函數的情況
如果基類中的成員函數被定義為虛函數,并且在派生類中也實現了該函數,則通過“指向派生類的基類指針” 訪問虛函數,訪問的是派生類中的實現。允許“基類指針指向派生類”這個操作,最大的意義也就在此,通過虛函數和函數覆蓋,實現了“多態”(指向不同的派生類,實現不同功能)。
Father f1;
Son s1;
Father* f = &s1;
f->print(); //調用派生類成員函數
3. 派生類指針指向基類對象
會產生編譯錯誤。基類對象無法被當作派生類對象,派生類中可能具有只有派生類才有的成員或成員函數。
即便是使用強制轉換,將派生類指針強制轉換成基類指針,通過這個“強制指向基類的派生類指針”訪問的函數依然是派生類的成員函數。
Father f1;
Son s1;
Son* s=&s1;
Father* f = (Father*) s;
f->print(); //調用派生類成員函數
綜上,可以通過基類指針訪問派生類方法(強制轉換和虛函數),不存在通過派生類指針調用基類成員函數的方法(即便是強制轉換)。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對億速云的支持。如果你想了解更多相關內容請查看下面相關鏈接
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。