過載,重定義與隱藏
阿新 • • 發佈:2019-02-13
過載:在同一個類中,要求函式名相同,函式引數不同
重定義:在基類與派生類之間,派生類重新定義基類中的函式,且要求函式的名稱、引數型別以及返回值型別完全一致。如果基類中的函式為virtual,則通過基類指標指向派生類時,可以實現多型。如果是非virtual,通過基類指標,不論指向的是基類還是派生類,所呼叫的都是基類的函式;通過派生類指標,呼叫的則是派生類的函式。(即實際呼叫的函式由指標的靜態型別決定,即指標定義為什麼型別,其靜態型別就是什麼型別)
隱藏:在基類和派生類之間,派生類定義了基類中的同名函式,但是引數可以不同。當引數不同的時候,對於派生類物件、指標、引用,其基類該同名函式都被隱藏了。(在virtual情況下,屬於重定義)
class Base { public: void f() {cout<<"Base:f"<<endl;} void f(int a) {cout<<"Base:f(int)"<<endl;} virtual void g() {cout<<"Base:g()"<<endl;} virtual void h() {cout<<"Base:h()"<<endl;} }; class Derived:public Base { public: void f(float) {cout<<"Derived:f(float)"<<endl;} void f(int) {cout<<"Derived:f(int)"<<endl;} void g(int) {cout<<"Derived:g(int)"<<endl;} void h() {cout<<"Derived:h()"<<endl;} }; int main() { Base *p1,*p2; Derived *d1; Base b;Derived d; p1=&b; p2=&d; d1=&d; p1->f(2);//指標的靜態型別為Base,直接呼叫Base中的f(int) p2->f(2);//指標的靜態型別為Base,直接呼叫Base中的f(int) p2->f(2.222);//將2.222轉換為了int,指標的靜態型別為Base,直接呼叫Base中的f(int) p2->g();//指標的靜態型別為Base,直接呼叫Base中的g(),因為在Derived中並沒有重新定義g(),所以虛擬函式表中,指向的函式Base中的g() p2->h();//指標的靜態型別為Base,直接呼叫Base中的h(),但這時候虛擬函式表中的h()已經替換成了Derived中的h() //d1->f();//編譯不通過,Derived中沒有無參的f d1->f(2);//指標的靜態型別為Derived,直接呼叫Derived中的f(int) //d1->g();//編譯不通過,Derived中沒有無參的g d1->g(2);//指標的靜態型別為Derived,直接呼叫Derived中的g(int) cout<<"****************"<<endl; d1=(Derived*)p1; d1->h();//動態函式由所指物件決定 d1->f(2);//靜態函式由指標的靜態型別決定 d1=(Derived*)p2; d1->f(2); p1=d1; p1->f(2); return 0; }