C++學習筆記24,方法重寫與方法隱藏
阿新 • • 發佈:2019-01-30
轉載請註明出處:
方法重寫.是指在子類中重新編寫父類中的虛函式的實現.要求子類中的函式必須跟父類中的原型一致.
包括返回值型別(協變返回型別不算)以及引數的數目,排列順序.
#include <iostream> #include <string> using namespace std; class base{ public: virtual void show(int i,string s){ cout<<i<<"+"<<s<<endl; cout<<"This is base show!"<<endl; } }; class dirved:public base{ public: virtual void show(int i,string s){ cout<<i<<"&"<<s<<endl; cout<<"This is dirved show!"<<endl; } }; int main(){ base b; b.show(10,"base"); dirved d; d.show(20,"dirved"); }
通過方法的重寫,即可定義同一函式在繼承層次中的不同行為!
如果在子類中使用父類虛方法的名稱,但是引數不同,那麼這個不是重寫父類的方法,也不會過載方法,而是建立一個新方法.
#include <iostream> #include <string> using namespace std; class base{ public: virtual void show(int i,string s){ cout<<i<<"+"<<s<<endl; cout<<"This is base show!"<<endl; } }; class dirved:public base{ public: /* virtual void show(int i,string s){ cout<<i<<"&"<<s<<endl; cout<<"This is dirved show!"<<endl; }*/ virtual void show(){ cout<<"This is void dirved show!"<<endl; } }; int main(){ base b; b.show(10,"base"); dirved d; //d.show(20,"dirved"); d.show(); }
這個時候,父類中的show()方法將被隱藏,即dirved類中無法再使用show(int,string)方法.
編譯結果:#include <iostream> #include <string> using namespace std; class base{ public: virtual void show(int i,string s){ cout<<i<<"+"<<s<<endl; cout<<"This is base show!"<<endl; } }; class dirved:public base{ public: /* virtual void show(int i,string s){ cout<<i<<"&"<<s<<endl; cout<<"This is dirved show!"<<endl; }*/ virtual void show(){ cout<<"This is void dirved show!"<<endl; } }; int main(){ base b; b.show(10,"base"); dirved d; d.show(20,"dirved"); d.show(); }
可以看出,對於dirved類來說,show(int,string)這個方法被隱藏起來了,即對於dirved物件來說不可見了!因此只要在子類中重新定義了父類的虛方法,父類中的所有與該方法過載的方法都將被隱藏!
這一點需要特別注意!
下面再看一些有趣的東西:
#include <iostream>
#include <string>
using namespace std;
class base{
public:
virtual void show(int i,string s){
cout<<i<<"+"<<s<<endl;
cout<<"This is base show!"<<endl;
}
};
class dirved:public base{
public:
virtual void show(int i,string s){
cout<<i<<"&"<<s<<endl;
cout<<"This is dirved show!"<<endl;
}
};
int main(){
dirved d;
d.show(10,"show()");
base &ref=d;
ref.show(100,"ref show()");
}
子類中正確的重寫了父類中的show方法,
結果沒有疑問.但是如果你重寫子類的show方法的時候,發現應該用double代替int,於是i更改為
#include <iostream>
#include <string>
using namespace std;
class base{
public:
virtual void show(int i,string s){
cout<<i<<"+"<<s<<endl;
cout<<"This is base show!"<<endl;
}
};
class dirved:public base{
public:
virtual void show(double i,string s){
cout<<i<<"&"<<s<<endl;
cout<<"This is dirved show!"<<endl;
}
};
int main(){
dirved d;
d.show(10,"show()");
base &ref=d;
ref.show(100,"ref show()");
}
執行結果:
看到沒有!最後那個ref.show(int,string)呼叫了base裡面的show方法!(100可以換成9.8更明顯)
明明是dirved物件的引用,怎麼就呼叫了base裡面的show方法呢?因為這實際上是建立了一個新方法!
可用override關鍵字來避免這種情況!
#include <iostream>
#include <string>
using namespace std;
class base{
public:
virtual void show(int i,string s){
cout<<i<<"+"<<s<<endl;
cout<<"This is base show!"<<endl;
}
};
class dirved:public base{
public:
virtual void show(double i,string s)override{
cout<<i<<"&"<<s<<endl;
cout<<"This is dirved show!"<<endl;
}
};
int main(){
dirved d;
d.show(10,"show()");
base &ref=d;
ref.show(95.9,"ref show()");
}
override表示你是想要重寫base類的show方法而不是建立一個新的show方法,因此如果引數不對就會報錯!
需要注意的是,即便是重寫,只要在子類中重新定義了,父類中的相應過載函式都將會被隱藏!
如果不想既想使用父類中的show,又想重寫某一個show(),可以利用using
#include <iostream>
#include <string>
using namespace std;
class base{
public:
virtual void show(int i,string s){
cout<<i<<"+"<<s<<endl;
cout<<"This is base show!"<<endl;
}
virtual void show(){
cout<<"this is a void show"<<endl;
}
};
class dirved:public base{
public:
//using
using base::show;
virtual void show(int i,string s)override{
cout<<i<<"&"<<s<<endl;
cout<<"This is dirved show!"<<endl;
}
};
int main(){
dirved d;
d.show(10,"show()");
base &ref=d;
ref.show(95.9,"ref show()");
d.show();
}
這樣就兩全其美啦!