1.1 覆蓋隱藏重載 重載,隱藏(重定義),覆蓋(重寫)—這幾個名詞看著好像很像,不過其實一樣都不一樣!! 1.1.1 重載:(1) 概念:在同一個作用域內;函數名相同,參數列表不同(參數個數不同,或者參數類型不同,或者參數個數和參數類型都不同),返回值類型可相同也可不同;這種情況叫做c++的重載! 注意:c語言沒有函數重載的機制;
(2)舉例: #include<iostream> using namespace std; int Add(int a,int b) { return a+b; } float Add(float a,float b) { return a+b; } int main() { cout<<Add(4,5)<<endl;//調用 int Add(int a,int b) cout<<Add(2.5f,3.7f)<<endl;//調用 float Add(float a,float b) return 0; }
|
此時,兩個函數Add();在同一作用域,函數名相同都是Add,參數類型不同;就構成了c++中的函數重載; (3)c++函數重載達到的效果:調用函數名相同的函數,會根據實參的類型和實參順序以及實參個數選擇相應的函數; (4)c++函數重載是一種靜態多態(又叫做靜態聯編,靜態綁定,靜態決議) 1.1.2 覆蓋(又叫重寫)(1)說覆蓋之前先說一個概念: 虛函數:類的成員函數前面加virtual關鍵字,則這個成員函數稱為虛函數 (2)覆蓋(重寫)的前提條件:父類函數為虛函數; (3)覆蓋(重寫)的概念:當在子類中定義了一個與父類完全相同的虛函數時,則稱子類的這個函數重寫(也稱覆蓋)了父類的這個虛函數。 (4)什么是在子類中定義了一個與父類完全相同的虛函數: 有兩種情況: 1.就是說子類中的虛函數和父類中的虛函數,函數名,參數個數,參數類型,返回值類型都相同;這種情況下子類的這個虛函數重寫的父類中的虛函數,構成了重寫; 2、協變—是說子類中的虛函數和父類中的虛函數,函數名,參數個數,參數類型都相同,只是返回值類型不同;父類的虛函數返回父類的指針或者引用,子類虛函數返回子類的指針或者引用;這種情況下子類的這個虛函數也重寫了父類中的虛函數,也構成了重寫;——我們把這種特殊的情況叫做協變 注意: 在子類中定義了一個與父類虛函數完全相同的函數,那么這個子類的函數就是重寫了父類的虛函數,此時這個子類的函數就是虛函數,如果不顯示的加上virtual修飾,編譯器也會默認為虛函數; (5)覆蓋(重寫)達到的效果: 1.在子類中重寫了父類的虛函數,那么子類對象調用該重寫函數,調用到的是子類內部重寫的虛函數,而并不是從父類繼承下來的虛函數;(這其實就是動態多態的實現); 2.在子類中重寫了父類的虛函數,如果用一個父類的指針(或引用)指向(或引用)子類對象,那么這個父類的指針或用引用調用該重寫的虛函數,調用的是子類的虛函數;相反,如果用一個父類的指針(或引用)指向(或引用)父類的對象,那么這個父類的指針或用引用調用該重寫的虛函數,調用的是父類的虛函數 (6)舉例1:普通重寫+函數重載 //普通重寫+函數重載 #include<iostream> using namespace std; class Person//父類 { public: virtual void BuyTickets()//父類虛函數 { cout<<" 買票-全票"<< endl; } protected : string _name; // 姓名 }; class Student : public Person//子類 { public: void BuyTickets()//子類虛函數 { cout<<" 買票-半價"<<endl ; } protected : int _num ; //學號 }; void Fun (Person* p) { p->BuyTickets(); } void Fun (Person&p) { p.BuyTickets(); } void Test () { Person p ; Student s; Fun(p); Fun(s); Fun(&p); Fun(&s); } int main() { Test(); return 0; }
|
1.1.3 隱藏(重定義)(1)隱藏(重定義)概念: 是指在不同的作用域中(分別在父類和子類中),函數名相同,不能構成重寫的都是重定義。 (2)隱藏(重定義)的使用范圍: 重定義的不光是類的成員函數,還可以是類的成員變量; (3)隱藏(重定義)的直接效果: 如果在父類和子類中有相同名字的成員;那么在子類中。會將父類的成員隱藏;隱藏以后的直接效果就是:無論在子類的內部或者外部(通過子類成員)訪問該成員;全都是訪問子類的同名成員;如果在子類內部或者外部(通過子類成員)訪問同名的成員函數,則需要根據函數調用的規則來調用子類的同名成員函數;否則調用失敗; #include<iostream> using namespace std; class A { protected: A(int x=2) :_a(x) {} //public: // //1 // void show() // { // cout<<"A::shou()"<<endl; // } //public: // //2 // virtual void show() // { // cout<<"A::shou()"<<endl; // } public: //3 void show(int a) { cout<<"A::shou()"<<endl; } public: int _a; }; class B:public A { public: B(int x=1) :_a(x) {} //public: // //1 // void show(int b) // { // cout<<"B::shou()"<<endl; // } //public: // //2 // void show(int a) // { // cout<<"B::shou()"<<endl; // } public: //3 void show(int a,int b) { cout<<"B::shou()"<<endl; cout<<_a<<endl; } public: int _a; }; int main() { B b; cout<<(b._a)<<endl; b.show(1); return 0; }
|
程序中所標明的1,2,3三種情況都是成員隱藏!
|