(继承)virtual与访问控制
之前只注意過訪問控制與繼承的關系,這邊不多說,今天看到代碼看到virtual放在private里,并且還有派生類沒有override public里的virtual,此時調用時啥情況了,這邊有點暈,看下面代碼
首先最基本的多態代碼
#include <iostream> #include <string>using namespace std;class animal { public://animal();//~animal();virtual void speakout(){cout << "animal voice voice voice" << endl;} }; class cat :public animal { public://cat();//~cat();virtual void speakout(){cout << "cat miao miao miao" << endl;} };int main() {cat ocat;animal *panimal = &ocat;panimal->speakout();getchar();}運行結果沒有任何問題,結果如下:
如果virtual是私有的,代碼如下:
#include <iostream> #include <string>using namespace std;class animal { private://animal();//~animal();virtual void speakout(){cout << "animal voice voice voice" << endl;} }; class cat :public animal { private://cat();//~cat();virtual void speakout(){cout << "cat miao miao miao" << endl;} };int main() {cat ocat;animal *panimal = &ocat;panimal->speakout();getchar();}編譯就會報錯,報錯如下,實際上此時放在private里的時候,virtual有和沒有一樣,都是類的私有成員,只有類內部成員以及友元能夠訪問
主要是考慮下面一種特殊情況,基類里有virtual A(),派生類繼承的時候沒有override A(),切A()會調用私有的private virtual,代碼如下:
#include <iostream> #include <string>using namespace std;class animal { public:virtual void speak(){speakout();} private://animal();//~animal();virtual void speakout(){cout << "animal voice voice voice" << endl;} }; class cat :public animal { private://cat();//~cat();virtual void speakout(){cout << "cat miao miao miao" << endl;} };int main() {cat ocat;animal *panimal = &ocat;panimal->speak();getchar();}其運行結果如下:
?
再對比如下代碼:
#include <iostream> #include <string>using namespace std;class animal { public:virtual void speak(){speakout();} private://animal();//~animal();void speakout(){cout << "animal voice voice voice" << endl;} }; class cat :public animal { private://cat();//~cat();void speakout(){cout << "cat miao miao miao" << endl;} };int main() {cat ocat;animal *panimal = &ocat;panimal->speak();getchar();}?其運行結果如下:
說明此時的private里的virtual是不能去掉的,如果去掉的話,speak()調用的是類本身的私有函數speakout(),否則調用的是派生類cat里的speakout()函數
?
當派生類繼承了基類里的public speak(),哪怕沒做任何修改,去掉private里的virtual,結果調用也是派生類里的speakout(),代碼如下:
#include <iostream> #include <string>using namespace std;class animal { public:virtual void speak(){speakout();} private://animal();//~animal();void speakout(){cout << "animal voice voice voice" << endl;} }; class cat :public animal { public:virtual void speak(){speakout();} private://cat();//~cat();void speakout(){cout << "cat miao miao miao" << endl;} };int main() {cat ocat;animal *panimal = &ocat;panimal->speak();getchar();}
運行結果如下:
只能猜測派生類沒有繼承基類里的public speak(),panimal->speak()調用的是基類里的speak()函數,這時候間接調用的speakout()如果是虛函數則調用派生類的(哪怕是private),否則調用基類的
當繼承了基類里的public speak(),panimal->speak()直接就調用了派生類里的speakout(),這時候speakout()是不是虛函數已沒有關系
?
?
這邊的原理我也沒搞懂,只知道現在用起來是這樣,如果哪位大神知道原理的能和我講下,不甚感激!!!!!!!!!!!
轉載于:https://www.cnblogs.com/effortscodepanda/p/6880596.html
總結
以上是生活随笔為你收集整理的(继承)virtual与访问控制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python对文件夹内文件去重
- 下一篇: Lua随机问题