成員函數的重載,覆蓋和隱藏是三個很容易混淆的概念,下面我們來區分一下這三者
一 重載的特點
1 兩個函數處於同一作用域中(即同一個類中)
2 函數名要相同
3 參數不相同(參數的個數,參數的類型,參數的順序)
4 返回值可同可不同
5 virtual關鍵字可有可無
二 覆蓋(重寫)的特點
1 兩個在不同作用域中(基類與派生類)
2 函數名相同
3 參數相同
4 基類必須要有virtual關鍵字
5返回值類型相同(除了協變)
此時基類的該函數被派生類的同名函數覆蓋
三 隱藏的特點
1 兩個函數處於不同的作用域中(基類與派生類)
2 函數名相同但是參數不同,無論有無virtual,基類的函數被派生類的同名函數隱藏
3 函數名相同,參數相同,基類中該函數沒有virtual關鍵字,基類的函數被派生類的同名函數隱藏
下面看個例子體會下隱藏和覆蓋的區別:
class Base
{
public:
Base(int x)
{
a = x;
}
virtual void f1()
{
cout <<a<<" "<< "Base::f1 ()" << endl;
}
int f2()
{
cout << a << " " << "Base::f2() " << endl;
return 0;
}
void f3()
{
cout << a << " " << "Base::f3() " << endl;
}
virtual Base*f4() //協變,還可爲 virtual Base&f4()
{
cout << a << " " << "Base::f4()" << endl;
return this;
}
private:
int a;
};
class Derived :public Base
{
public:
Derived(int x, int y) :Base(x), b(y){}
virtual void f1()
{
cout << b << " " << "Derived::f1 () " << endl;
}
void f2()
{
cout << b << " " << "Derived::f2() " << endl;
}
void f3(int)
{
cout << b << " " << "Derived::f3()" << endl;
}
virtual Derived*f4() //協變還可爲virtual Derived&f4()
{
cout << b << " " << "Derived::f4()" << endl;
return this;
}
private:
int b;
};
int main()
{
Base b(1);
Derived d(2, 3);
Base*pb = &b;
pb->f1();// 1 Base :: f1()
pb->f2();// 1 Base :: f2()
pb->f3();// 1 Base :: f3()
pb->f4();// 1 Base :: f4()
pb = &d;
pb->f1();//3 Derived :: f1()
pb->f2();//2 Base :: f2()
pb->f3();//2 Base :: f3()
pb->f4();//3 Derived :: f4()
return 0;
}
Derived 中f1,f4函數重寫了Base中f1,f4
f2,f3隱藏了Base中f2,f3