重載與覆蓋的區別1
經常看到C++的一些初學者對於重載、覆蓋、多態與函數隱藏的模糊理解。在這裏寫一點自己的見解,希望能夠C++初學者解惑。
要弄清楚重載、覆蓋、多態與函數隱藏之間的複雜且微妙關係之前,我們首先要來回顧一下重載覆蓋等基本概念。
⑴首先,我們來看一個非常簡單的例子,理解一下什麼叫函數隱藏hide。
#include <iostream>
using namespace std;
class Base
{
public:
void fun() { cout << "Base::fun()" << endl; }
};
class Derive : public Base
{
public:
void fun(int i) { cout << "Derive::fun()" << endl; }
};
int main()
{
Derive d;
//下面一句錯誤,故屏蔽掉
//d.fun();error C2660: ''''fun'''' : function does not take 0 parameters
d.fun(1);
Derive *pd =new Derive();
//下面一句錯誤,故屏蔽掉
//pd->fun();error C2660: ''''fun'''' : function does not take 0 parameters
pd->fun(1);
delete pd;
return 0;
}
/*在不同的非命名空間作用域裏的函數不構成重載,子類和父類是不同的兩個作用域。
在本例中,兩個函數在不同作用域中,故不夠成重載,除非這個作用域是命名空間作用域。*/
在這個例子中,函數不是重載overload,也不是覆蓋override,而是隱藏hide。
接下來的5個例子具體說明一下什麼叫隱藏
例1
#include <iostream>
using namespace std;
class Basic
{
public:
void fun(){cout << "Base::fun()" << endl;}//overload
void fun(int i){cout << "Base::fun(int i)" << endl;}//overload
};
class Derive :public Basic
{
public:
void fun2(){cout << "Derive::fun2()" << endl;}
};
int main()
{
Derive d;
d.fun();//正確,派生類沒有與基類同名函數聲明,則基類中的所有同名重載函數都會作爲候選函數。
d.fun(1);//正確,派生類沒有與基類同名函數聲明,則基類中的所有同名重載函數都會作爲候選函數。
return 0;
}
例2
#include <iostream>
using namespace std;
class Basic{
public:
void fun(){cout << "Base::fun()" << endl;}//overload
void fun(int i){cout << "Base::fun(int i)" << endl;}//overload
};
class Derive :public Basic{
public:
//新的函數版本,基類所有的重載版本都被屏蔽,在這裏,我們稱之爲函數隱藏hide
//派生類中有基類的同名函數的聲明,則基類中的同名函數不會作爲候選函數,即使基類有不同的參數表的多個版本的重載函數。
void fun(int i,int j){cout << "Derive::fun(int i,int j)" << endl;}
void fun2(){cout << "Derive::fun2()" << endl;}
};
int main()
{
Derive d;
d.fun(1,2);
//下面一句錯誤,故屏蔽掉
//d.fun();error C2660: ''''fun'''' : function does not take 0 parameters
return 0;
}
例3
#include <iostream>
using namespace std;
class Basic{
public:
void fun(){cout << "Base::fun()" << endl;}//overload
void fun(int i){cout << "Base::fun(int i)" << endl;}//overload
};
class Derive :public Basic{
public:
//覆蓋override基類的其中一個函數版本,同樣基類所有的重載版本都被隱藏hide
//派生類中有基類的同名函數的聲明,則基類中的同名函數不會作爲候選函數,即使基類有不同的參數表的多個版本的重載函數。
void fun(){cout << "Derive::fun()" << endl;}
void fun2(){cout << "Derive::fun2()" << endl;}
};
int main()
{
Derive d;
d.fun();
//下面一句錯誤,故屏蔽掉
//d.fun(1);error C2660: ''''fun'''' : function does not take 1 parameters
return 0;
}
例4
#include <iostream>
using namespace std;
class Basic{
public:
void fun(){cout << "Base::fun()" << endl;}//overload
void fun(int i){cout << "Base::fun(int i)" << endl;}//overload
};
class Derive :public Basic{
public:
using Basic::fun;
void fun(){cout << "Derive::fun()" << endl;}
void fun2(){cout << "Derive::fun2()" << endl;}
};
int main()
{
Derive d;
d.fun();//正確
d.fun(1);//正確
return 0;
}
/*
輸出結果
Derive::fun()
Base::fun(int i)
Press any key to continue
*/
例5
#include <iostream>
using namespace std;
class Basic{
public:
void fun(){cout << "Base::fun()" << endl;}//overload
void fun(int i){cout << "Base::fun(int i)" << endl;}//overload
};
class Derive :public Basic{
public:
using Basic::fun;
void fun(int i,int j){cout << "Derive::fun(int i,int j)" << endl;}
void fun2(){cout << "Derive::fun2()" << endl;}
};
int main()
{
Derive d;
d.fun();//正確
d.fun(1);//正確
d.fun(1,2);//正確
return 0;
}
/*
輸出結果
Base::fun()
Base::fun(int i)
Derive::fun(int i,int j)
Press any key to continue
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.