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++基础与提高》 王桂林

posted @ 2021-10-31 12:29  bruce628  阅读(895)  评论(0编辑  收藏  举报