環境:QT 5.12
繼承方式規定了子類如何訪問從基類繼承的成員。繼承方式有public、protected、private三種。繼承方式不影響派生類的訪問權限,影響了從基類繼承而來的成員的訪問權限,包括派生類內的訪問權限和派生類對象的訪問權限。在派生類內,對於從基類繼承下來的數據成員而言,就有四種情況了,分別是public、protected、private、invisible(不可見)。
以下列出結論,然后使用代碼進行驗證。
1.protected繼承,基類中的public成員和protected成員在派生類中均為protected成員,基類中的private成員在派生類中為invisiable,無法訪問。多次protected繼承后,基類中public成員和protected成員在孫子類中仍然為protected成員。
1) 初始代碼如下
類A中有public、protected、private三種屬性的成員變量,類B繼承類A,繼承方式為protected,類B中也有public、protected、private三種屬性的成員變量。
1 #include <iostream> 2 3 using namespace std; 4 5 class A 6 { 7 public: 8 A(int three) 9 :a_three(three){} 10 11 int a_three; 12 protected: 13 int a_two = 20; 14 private: 15 int a_one = 30; 16 }; 17 18 class B: protected A 19 { 20 public: 21 B(int three_1, int three_2) 22 :A(three_1), b_three(three_2){} 23 24 int b_three; 25 26 void display() 27 { 28 cout<<"A::a_three: "<<a_three<<endl; 29 cout<<"A::a_two : "<<a_two<<endl; 30 } 31 protected: 32 int b_two= 50; 33 private: 34 int b_one = 60; 35 }; 36 37 int main() 38 { 39 B bb(10, 30); 40 bb.display(); 41 42 return 0; 43 }
運行結果
派生類B中public函數display(),可以訪問從基類繼承而來的public成員和protected成員,因為這兩個成員在派生類中作為派生類的protected成員了。
2) 再添加上孫子類,類C繼承類B,繼承方式為protected。
1 class C: protected B 2 { 3 public: 4 C(int three_1, int three_2, int three_3) 5 :B(three_1, three_2), c_three(three_3){} 6 7 int c_three; 8 9 void show() 10 { 11 cout<<"A::a_three: "<<a_three<<endl; 12 cout<<"A::a_two : "<<a_two<<endl; 13 cout<<"A::b_three: "<<b_three<<endl; 14 cout<<"A::b_two : "<<b_two<<endl; 15 } 16 protected: 17 int c_two = 80; 18 private: 19 int c_one = 90; 20 };
在孫子類C中public函數show()內打印祖父類A中的public和protected數據成員。main函數也進行相應的調整,調用類C中show()函數。
1 int main() 2 { 3 B bb(10, 30); 4 bb.display(); 5 6 cout<<"----------"<<endl; 7 C cc(10, 30, 70); 8 cc.show(); 9 //cout<<cc.a_three<<endl; 10 //cout<<cc.a_two<<endl; 11 //cout<<cc.b_three<<endl; 12 //cout<<cc.b_three<<endl; 13 14 return 0; 15 }
運行結果
在孫子類C中,仍然可以訪問祖父類A中的public和protected成員a_three、a_two(還有父類B中的public、protected成員b_three、b_two),符合結論1。孫子類的對象cc不能直接訪問這些成員,也證實了從基類繼承下來的public和protected成員,到了派生類中確是protected屬性。
2.private繼承,基類中的public成員和protected成員在派生類中均為private成員,基類中的private成員在派生類中為invisible,無法訪問。多次private繼承后,最初的基類中的成員在孫子類中均為invisible,無法訪問。
當我們將上面代碼中類B的繼承方式和類C的繼承方式由protected修改為private時
第60、61兩行代碼沒有報錯,在類B的成員函數display()中,它是可以訪問基類A中的public、protected成員a_three、a_two。
第47、48兩行代碼報錯,在孫子類C的成員函數show()中,提示它不可以訪問祖父類A中的public、protected成員a_three、a_two。
說明這兩個數據成員a_three、a_two在類C的父類B中,是類B的private成員,private成員在派生類中是invisible。第60、61兩行代碼,類內部可以訪問自己的private數據成員(private繼承后,父類A的public和proteced成員在派生類B中成為派生類B的private成員),符合預期。
參考資料:
《C++基礎與提高》 王桂林