我们之前在学习继承的时候,冒号(:)表示继承关系,Parent 表示被继承的类,而 public 的意义又是什么呢?我们知道,C++ 中的跟 public 对应的关键字还有 protected 和 private,那么是否可以将继承语句中的 public 换成 protected 或者 private 呢?如果可以的话,它们与 public 继承又有什么区别呢?

我们来尝试下

#include<iostream>#include<string>usingnamespacestd;classParent{};classChild_A:publicParent{};classChild_B:protectedParent{};classChild_C:privateParent{};intmain(){return0;}

我们来编译下,看看编译器是否能通过呢?

我们看到编译通过了,证明这样写编译器是支持的。也就说明了继承不止 public 这一种继承,那么在 C++ 中支持三种不同的继承方式:a> public 继承:父类成员在子类中保持原有访问级别;b> private 继承:父类成员在子类中变成私有成员;c> protected 继承:父类中的公有成员变为保护成员,其它成员保持不变。通过下面这张表我们更能清晰的认识

那么继承成员的访问属性 = MAX {继承方式,父类成员的访问属性}。在 C++ 中的默认继承方式为 private!!!

下来我们通过一个示例代码看看继承与访问级别的深度实践

#include<iostream>#include<string>usingnamespacestd;classParent{private:intm_a;protected:intm_b;public:intm_c;voidset(inta,intb,intc){m_a=a;m_b=b;m_c=c;}};classChild_A:publicParent{public:voidprint(){cout<<"m_a="<<m_a<<endl;cout<<"m_b="<<m_b<<endl;cout<<"m_c="<<m_c<<endl;}};classChild_B:protectedParent{public:voidprint(){cout<<"m_a="<<m_a<<endl;cout<<"m_b="<<m_b<<endl;cout<<"m_c="<<m_c<<endl;}};classChild_C:privateParent{public:voidprint(){cout<<"m_a="<<m_a<<endl;cout<<"m_b="<<m_b<<endl;cout<<"m_c="<<m_c<<endl;}};intmain(){Child_Aa;Child_Bb;Child_Cc;/*a.m_c=10;b.m_c=10;c.m_c=10;a.set(1,1,1);b.set(2,2,2);c.set(3,3,3);a.print();b.print();c.print();*/return0;}

我们定义的三个 Child 分别是 public、protected、private 继承的,看看编译会通过嘛?

我们看到编译出错了,因为在父类中它是私有成员,所以在子类对象中不能使用。我们将父类中的 private 属性改为 protected,看看子类继承还会出错嘛

编译通过了,我们再来将利用子类对象改变其父类的 public 成员变量改变的三行语句注释去掉,看看编译能通过嘛

我们看到编译又报错了,因为 Child_B 保护继承自 Parent, 所以所有的 public 成员全部变成了 protected 成员, 因此外界无法访问;Child_C 私有继承自 Parent, 所以所有的 成员全部变成了 private 成员, 因此外界无法访问。我们注释掉两句,再来将下面 3 句调用父类的 set 函数的实数去掉,编译看看

编译结果跟之前的一样,那么我们注释掉,再来看看直接调用它们自己内部定义的函数 print 呢

我们看到编译正常通过。那么我们经过这么多的实验,也应该是明白了三种方式继承的用法了。不过在现代的 C++ 项目工程中,我们一般只使用 public 继承。同样,C++ 的派生语言也只支持一种继承方式(public 继承),因为 protected 和 private 继承带来的复杂性远大于实用性。

通过对继承方式的学习,总结如下:1、C++ 中支持 3 中不同的继承方式;2、继承方式直接影响父类成员在子类中的访问属性;3、一般而言,在工程中只使用 public 的继承方式;4、C++ 的额派生语言中只支持 public 继承方式。


欢迎大家一起来学习 C++ 语言,可以加我QQ:243343083。