***************************************************
更多精彩,歡迎進入:http://shop115376623.taobao.com
***************************************************
C++成員函數重載、覆蓋和隱藏的區別
class Base
{
? public:
void Walk(int x){ cout <<"Base::Walk(int)"<< endl; }
void Walk(float x){cout<<"Base::Walk(float)"<<endl;}
virtual void Run(void){cout<<"Base::Run(void)"<<endl;}
};
class Derived: public Base
{
public:
virtual void Run(void){cout<<"Derived::Run(void)"<<endl;}
};
// 如上關系是: Base::Walk(float)和Base::Walk(int)是函數重載關系
? ? ? ? ? ? ? ?Derived::Run(void)覆蓋了Base::Run(void),而不是虛函數重載
int main()
{
Derived der;
Base *pb = &der;
pb->Walk(20); ? ? ?// 調用 Base::Walk(int)
pb->Walk(1.2f); ? ?// 調用 Base::Walk(float)
pb->Run(); ? ? ? ? // 調用 Derived::Run(void)
return 0;
}
如果使用pb->Walk(1.2)的話(即參數為double類型)則編譯無法通過
原因是double轉換為int和float都是合理的,但兩者同時存在導致二義性,編譯無法通過
下面介紹重載和覆蓋的區別
重載函數被重載的特征:
1. 具有相同的作用域
2. 函數名字相同
3. 參數類型、 順序或數目不同
覆蓋指派生類重新實現基類的成員函數,其特征是:
1. 不同作用域
2. 函數完全相同(包括函數名稱和參數列表)
3. 基類函數必須是虛函數
經常聽到的“虛函數重載”這一說法是不正確的,應該是覆蓋,“虛函數重載”實質上是告訴編譯器將函數指針
替換重父類繼承下來虛函數列表的對象項而實現,這么覺得還是翻譯成覆蓋比較合適
class Base
{
? public:
virtual void Walk(float x){ cout <<"Base::Walk(float)"<< endl; }
void Run(float x){cout<<"Base::Run(float)"<<endl;}
void Jump(float x){cout<<"Base::Jump(float)"<<endl;}
};
class Derived: public Base
{
public:
virtual void Walk(float x){ cout <<"Derived::Walk(float)"<< endl; }
void Run(int x){cout<<"Derived::Run(int)"<<endl;}
void Jump(float x){cout<<"Derived::Jump(float)"<<endl;}
};
如上的關系是 Derived::Walk(float)覆蓋了函數Base::Walk(float)
? ? ? ? ? ? ?Derived::Run(int) 隱藏了Base::Run(int),Derived::Jump(float)隱藏了Base::Jump(float)
而不是重載(不在同一個作用域內),也不是覆蓋,因為函數不是虛函數
class Base
{
? public:
virtual void Walk(){ cout <<"Base::Walk()"<< endl; }
? ?void Run(float x){cout<<"Base::Run(float)"<<endl;}
};
class Derived: public Base
{
public:
virtual void Walk(int x){ cout <<"Derived::Walk(int)"<< endl; }
void Run(int x){cout<<"Derived::Run(int)"<<endl;}
};
int main()
{
Derived der;
Derived* pd = &der;
pd->Run(1); ? ? ? // 調用Derived::Run(int)
pd->Run(1.2f); ? ?// 調用Derived::Run(int) ? 證明Base::Run(float)被隱藏
pd->Walk(1); ? ? ?// ?Derived::Run(int)"
// pd->Walk();編譯無法通過,函數被隱藏
Base *pb = &der;
pb->Run(1); ? ? ? // 調用Base::Run(float)
pb->Run(1.2f); ? ?// 調用Base::Run(float)?
pb->Walk();
// pd->Walk(1);編譯無法通過,函數被隱藏
return 0;
}
class Base
{
? public:
void Walk(int x){ cout <<"Base::Walk(int)"<< endl; }
void Walk(float x){cout<<"Base::Walk(float)"<<endl;}
virtual void Run(void){cout<<"Base::Run(void)"<<endl;}
};
class Derived: public Base
{
public:
virtual void Run(void){cout<<"Derived::Run(void)"<<endl;}
};
// 如上關系是: Base::Walk(float)和Base::Walk(int)是函數重載關系
? ? ? ? ? ? ? ?Derived::Run(void)覆蓋了Base::Run(void),而不是虛函數重載
int main()
{
Derived der;
Base *pb = &der;
pb->Walk(20); ? ? ?// 調用 Base::Walk(int)
pb->Walk(1.2f); ? ?// 調用 Base::Walk(float)
pb->Run(); ? ? ? ? // 調用 Derived::Run(void)
return 0;
}
如果使用pb->Walk(1.2)的話(即參數為double類型)則編譯無法通過
原因是double轉換為int和float都是合理的,但兩者同時存在導致二義性,編譯無法通過
下面介紹重載和覆蓋的區別
重載函數被重載的特征:
1. 具有相同的作用域
2. 函數名字相同
3. 參數類型、 順序或數目不同
覆蓋指派生類重新實現基類的成員函數,其特征是:
1. 不同作用域
2. 函數完全相同(包括函數名稱和參數列表)
3. 基類函數必須是虛函數
經常聽到的“虛函數重載”這一說法是不正確的,應該是覆蓋,“虛函數重載”實質上是告訴編譯器將函數指針
替換重父類繼承下來虛函數列表的對象項而實現,這么覺得還是翻譯成覆蓋比較合適
class Base
{
? public:
virtual void Walk(float x){ cout <<"Base::Walk(float)"<< endl; }
void Run(float x){cout<<"Base::Run(float)"<<endl;}
void Jump(float x){cout<<"Base::Jump(float)"<<endl;}
};
class Derived: public Base
{
public:
virtual void Walk(float x){ cout <<"Derived::Walk(float)"<< endl; }
void Run(int x){cout<<"Derived::Run(int)"<<endl;}
void Jump(float x){cout<<"Derived::Jump(float)"<<endl;}
};
如上的關系是 Derived::Walk(float)覆蓋了函數Base::Walk(float)
? ? ? ? ? ? ?Derived::Run(int) 隱藏了Base::Run(int),Derived::Jump(float)隱藏了Base::Jump(float)
而不是重載(不在同一個作用域內),也不是覆蓋,因為函數不是虛函數
class Base
{
? public:
virtual void Walk(){ cout <<"Base::Walk()"<< endl; }
? ?void Run(float x){cout<<"Base::Run(float)"<<endl;}
};
class Derived: public Base
{
public:
virtual void Walk(int x){ cout <<"Derived::Walk(int)"<< endl; }
void Run(int x){cout<<"Derived::Run(int)"<<endl;}
};
int main()
{
Derived der;
Derived* pd = &der;
pd->Run(1); ? ? ? // 調用Derived::Run(int)
pd->Run(1.2f); ? ?// 調用Derived::Run(int) ? 證明Base::Run(float)被隱藏
pd->Walk(1); ? ? ?// ?Derived::Run(int)"
// pd->Walk();編譯無法通過,函數被隱藏
Base *pb = &der;
pb->Run(1); ? ? ? // 調用Base::Run(float)
pb->Run(1.2f); ? ?// 調用Base::Run(float)?
pb->Walk();
// pd->Walk(1);編譯無法通過,函數被隱藏
return 0;
}