环境:QT 5.12
继承方式规定了子类如何访问从基类继承的成员。继承方式有public、protected、private三种。继承方式不影响派生类的访问权限,影响了从基类继承而来的成员的访问权限,包括派生类内的访问权限和派生类对象的访问权限。在派生类内,对于从基类继承下来的数据成员而言,就有四种情况了,分别是public、protected、provate、invisiable(不可见)。
1.protected继承,基类中的public成员和protected成员在派生类中均为protected成员,基类中的private成员在派生类中为invisiable,无法访问。多次protected继承后,基类中protected成员在孙子类中仍然为protected成员。
1) 初始代码如下
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成员和protected成员,因为它们在派生类中作为派生类的protected成员了。
2) 再添加上孙子类
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 };
main函数进行相应的调整,尝试打印基类A中的public和protected成员。
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成员,到了派生类中确是protectef属性。
2.private继承,基类中的public成员和protected成员在派生类中均为private成员,基类中的private成员在派生类中为invisiable,无法访问。多次private继承后,基类中的成员在孙子类中均为invisiable,无法访问。
当我们将上面代码中类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,说明这两个数据成员是其父类B类中的private成员,private成员在派生类中是invisiable的。
参考资料:
《C++基础与提高》 王桂林