C++——多型
1.什麼是多型?
多型簡單的講就是“一個介面,多種方法”,程式在執行時才決定呼叫的函式,他是物件導向的核心概念。當多型應用形參的資料交,可以接受更多的型別,當多型用於返回值型別的時候,可以返回更多型別的資料,多型可以讓你的程式碼擁有更好的擴充套件性
構成多型的條件
- 繼承的存在
- 子類要重寫父類的虛擬函式
- 父類的指標/引用呼叫重寫虛擬函式
什麼是重寫:
- 不在同一作用域內(分別在父類和子類中)
- 基類函式必須是虛擬函式(virtual關鍵字)
- 函式名相同,引數相同,返回值相同(協變除外)
- 訪問修飾符可以不同(公有,保護…)
場景一:父類和子類都加virtual:
class person
{
public:
virtual void buytickets()
{
cout << "買票" << endl;
}
};
class student :public person
{
public:
virtual void buytickets()
{
cout << "買票——半價" << endl;
}
};
void Fun(person& p)
{
p.buytickets();
}
void Test()
{
person p;//父類物件
student s;//子類物件
Fun(p);
Fun(s);
}
輸出為:
當使用基類的指標或引用呼叫重寫的虛擬函式時,當指向父類物件呼叫的就是父類的虛擬函式,指向子類的物件就是呼叫子類的虛擬函式。
多型跟型別無關,跟物件有關
場景二:基類中函式不加virtual
構成多型時,父類的函式必須是虛擬函式(virtual),為什麼
class person
{
public:
void buytickets()
{
cout << "買票" << endl;
}
};
class student :public person
{
public:
virtual void buytickets()
{
cout << "買票——半價" << endl;
}
};
void Fun(person& p)
{
p.buytickets();
}
void Test()
{
person p;//父類物件
student s;//子類物件
Fun(p);
Fun(s);
}
- 輸出為:
- 如果將父類的virtual,那麼就不能構成多型,即使你建立了子類物件和父類物件,呼叫的也都是父類的函式//輸出“買票”。與物件無關,不能構成多型
- 而如果將子類中的virtual去掉,而父類中的還在,同樣可以構成多型。
場景三:派生類中函式不加virtual
class person
{
public:
virtual void buytickets()
{
cout << "買票" << endl;
}
};
class student :public person
{
public:
void buytickets()
{
cout << "買票——半價" << endl;
}
};
void Fun(person& p)
{
p.buytickets();
}
void Test()
{
person p;//父類物件
student s;//子類物件
Fun(p);
Fun(s);
}
輸出為:
2.多型的分類:
- 編譯時的多型性(靜態多型):靜態多型就是過載,因為是在編譯時即確定型別大小,所以稱為靜態多型。
- 執行時多型性(多型多型):通過繼承重寫基類的虛擬函式實現,在程式執行時決議確定,所以稱為動態
動態多型:上述程式碼即使動態多型
每一個帶有虛擬函式的物件都會有一個虛擬函式表,虛擬函式表裡存的時函式指標,呼叫的時候,指標就去虛擬函式表裡查詢。
發生重寫之後,下一次父類指向我們呼叫的fun()函式時,它呼叫到的就是子類的fun()函式。
多型:
- 多型是物件導向的三大特徵直以,分為靜態多型和多型多型
- 靜態多型包含函式過載與泛型程式設計,靜態多型是程式呼叫函式,編譯器決定使用那塊可執行程式碼塊
- 動態多型是由繼承機制及虛擬函式實現的,通過指向派生類的基類指標或引用,訪問派生類中透明覆蓋成員函式
- 多型的作用:把不同的子類物件都當作父類來看,可以遮蔽不同子類物件之間的差異,寫出通用的程式碼,做出通用的程式設計,一適應需求的不斷變化。
類成員函式中過載/重定義(隱藏)/重寫(覆蓋)的區別
1.函式過載:通常是一組功能相似但是引數型別不同的函式
- 函式要在相同的作用域中
- 函式名相同
- 函式的引數列表不同(引數個數,引數順序,引數型別),與返回值無關
2.函式覆蓋(重寫):覆蓋是指在派生類裡覆蓋基類的函式
- 函式在不同作用域中(基類和派生類)
- 倆個函式名相同/引數相同/返回值相同(協變除外)
- 基類必須是虛擬函式(派生類最好也是)
- 訪問修飾符可以不同
3.函式隱藏(重定義):派生類的函式遮蔽了與其名字相同的基類函式
- 函式的作用域不同(基類,派生類)
- 函式名相同(只要名字相同就可以構成隱藏)
- 如果派生類函式與基類函式引數相同,但是基類中沒有virtual,就構成函式隱藏
相關文章
- C++多型C++多型
- C++的多型C++多型
- C++多型性C++多型
- C++編譯期多型與執行期多型C++編譯多型
- 剖析C++多型:用C實現簡單多型C++多型
- C++整理16_多型C++多型
- 開心檔之C++ 多型C++多型
- C++多型之虛擬函式C++多型函式
- C++ 多型的實現及原理C++多型
- JAVA與C++的多型異同JavaC++多型
- C++和java多型的區別C++Java多型
- [c++] 繼承和多型整理二C++繼承多型
- c++學習(1)--C++封裝、繼承、多型C++封裝繼承多型
- C/C++—— C++編譯器是如何實現多型C++編譯多型
- C/C++—— 對多型現象的理解C++多型
- C++ 繼承、多型、虛擬函式C++繼承多型函式
- c++實現多型的方法 虛表C++多型
- C++多型(上)——虛擬函式、虛表C++多型函式
- 關於c語言模擬c++的多型C語言C++多型
- C++虛擬函式與多型實戰 (轉)C++函式多型
- C++八股之函式過載與重寫-靜態多型與動態多型C++函式多型
- 詳解C++中的多型和虛擬函式C++多型函式
- 虛擬函式表-C++多型的實現原理函式C++多型
- C++ 多型的實現原理與記憶體模型C++多型記憶體模型
- 重讀C++之一:封裝、繼承和多型C++封裝繼承多型
- 深入理解 C++ 中的多型與檔案操作C++多型
- C++整理17_執行時多型(晚繫結)C++多型
- c++菱形繼承、多型與類記憶體模型C++繼承多型記憶體模型
- 理解C++物件導向程式設計[多型性部分] (轉)C++物件程式設計多型
- C++(虛擬函式實現多型基本原理)C++函式多型
- C++ 轉型C++
- 多型。多型
- 多型~多型
- 多型多型
- c++學習心得第二期 多型+檔案操作C++多型
- C++ 一些學習筆記(十二)類和物件-多型C++筆記物件多型
- 第二十二篇:C++中的多型機制C++多型
- 【C++】C++之型別轉換C++型別