這是本人第一次寫博客,主要是想記錄自己的學習過程、心得體會,一是可以方便以后回顧相關知識,二是可以與大家相互學習交流。
關於C++中類成員函數的重載、覆蓋和隱藏區別,第一次看到這個問題是在准備找工作的時候在牛客網中(http://www.nowcoder.com/questionTerminal/266d3a6d4f1b436aabf1eff3156fed95)看到的,后來也有遇到一些題在考察這個知識點,只要理解了他們的區別,還是可以正確的解答有關這個知識點的題。看到牛客網中有大牛的解釋很好,故摘錄保存。
1.成員函數被重載的特征:
(1)相同的范圍(在同一個類中);
(2)函數名字相同;
(3)參數不同;
(4)virtual 關鍵字可有可無。
2.覆蓋是指派生類函數覆蓋基類函數,特征是:
(1)不同的范圍(分別位於派生類與基類);
(2)函數名字相同;
(3)參數相同;
(4)基類函數必須有virtual 關鍵字。
3.“隱藏”是指派生類的函數屏蔽了與其同名的基類函數,規則如下:
(1)如果派生類的函數與基類的函數同名,但是參數不同。此時,不論有無virtual關鍵字,基類的函數將被隱藏(注意別與重載混淆)。
(2)如果派生類的函數與基類的函數同名,並且參數也相同,但是基類函數沒有virtual 關鍵字。此時,基類的函數被隱藏(注意別與覆蓋混淆)。
有關重載,應該是很好理解的(在同一個類中,函數名相同,函數的參數類型和個數不同),此處不予更多的說明,對於覆蓋和隱藏(主要在基類和派生類中體現),借助下面這個例子來直觀的說明:
#include<iostream>
using namespace std;
class People {
public:
// 隱藏:是指派生類的函數屏蔽基類函數
// 隱藏規則1:
// 1) 函數名相同 && 參數不同
// 2) virtual不影響
void getId_different_params() {cout << "People::getId_different_params" << endl;}
virtual void getName_different_params() {cout << "People::getName_different_params" << endl;}
// 隱藏規則2:
// 1) 函數名相同 && 參數相同
// 2) 無virtual
void getPhone_same_params() {cout << "People::getPhone_same_params" << endl;}
// 覆蓋規則:
// 1) 函數名相同 && 參數相同
// 2) 有virtual
virtual void getAddress_same_params() {cout << "People::getAddress_same_params" << endl;}
};
class Children : public People {
public:
// 隱藏:是指派生類的函數屏蔽基類函數
// 隱藏規則1:
// 1) 函數名相同 && 參數不同
// 2) virtual不影響
void getId_different_params(int) {cout << "Children::getId_different_params(int)" << endl;}
virtual void getName_different_params(int) {cout << "Children::getName_different_params(int)" << endl;}
// 隱藏規則2:
// 1) 函數名相同 && 參數相同
// 2) 無virtual
void getPhone_same_params() {cout << "Children::getPhone_same_params" << endl;}
// 覆蓋規則:
// 1) 函數名相同 && 參數相同
// 2) 有virtual
virtual void getAddress_same_params() {cout << "Children::getAddress_same_params" << endl;}
};
void main()
{
Children *c = new Children();
c->getId_different_params(1);
c->getName_different_params(1);
c->getPhone_same_params();
c->getAddress_same_params();
/*輸出為:
Children::getId_different_params(int)
Children::getName_different_params(int)
Children::getPhone_same_params
Children::getAddress_same_params
*/
People *p = new Children();
p->getId_different_params();
p->getName_different_params();
p->getPhone_same_params();
p->getAddress_same_params();
/*輸出為:
People::getId_different_params //由於子類中的函數只是隱藏了基類中的函數而沒有覆蓋,因為指針為基類指針,故調用基類函數
People::getName_different_params //由於子類中的函數只是隱藏了基類中的函數而沒有覆蓋,因為指針為基類指針,故調用基類函數
People::getPhone_same_params //由於子類中的函數只是隱藏了基類中的函數而沒有覆蓋,因為指針為基類指針,故調用基類函數
Children::getAddress_same_params // 由於子類中的函數覆蓋了基類中的函數,雖然指針為基類指針,但是會調用子類函數
*/
}
