protected和private繼承方式的不同


環境: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++基礎與提高》 王桂林


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM