重載與覆蓋的區別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
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章