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

protected和private继承方式的不同的更多相关文章

  1. C++ public、protected、private 继承方式的区别

    访问修饰符 public.protected.private,无论是修饰类内成员(变量.函数),还是修饰继承方式,本质上实现的都是可见性的控制. Difference between private, ...

  2. c++三种继承方式public,protect,private

    C++中的三种继承public,protected,private 三种访问权限 public:可以被任意实体访问 protected:只允许子类及本类的成员函数访问 private:只允许本类的成员 ...

  3. C++中的三种继承public,protected,private

    ( c++默认class是private继承且class内的成员默认都是private struct 默认位public 继承,struct内成员默认是public  ) 三种访问权限 public: ...

  4. C++学习15 继承权限和继承方式

    C++继承的一般语法为: class 派生类名:[继承方式] 基类名{ 派生类新增加的成员 }; 继承方式限定了基类成员在派生类中的访问权限,包括 public(公有的).private(私有的)和 ...

  5. 3.2 C++继承方式

    参考: http://www.weixueyuan.net/view/6359.html  总结: 子类继承父类,继承方式将限制父类的成员属性在子类中的访问权限,子类访问父类的成员,也需要遵循其成员的 ...

  6. mfc 类三种继承方式下的访问

    知识点 public private protected 三种继承方式 三种继承方式的区别 public 关键字意味着在其后声明的所有成员及对象都可以访问. private 关键字意味着除了该类型的创 ...

  7. C++中public、protected、private的差别

    第一: private,public,protected的訪问范围:   private: 仅仅能由该类中的函数.其友元函数訪问,不能被不论什么其它訪问.该类的对象也不能訪问. protected: ...

  8. C++ 类中的3种访问权限和继承方式

    访问权限:public 可以被任意实体访问,protected 只允许子类(无论什么继承方式)及本类的成员函数访问,private 只允许本类的成员函数访问.三种继承方式分别是 public 继承,p ...

  9. [c++] C++中public、protected、private的区别

    转:https://blog.csdn.net/vanturman/article/details/79393317 第一: private,public,protected的访问范围: privat ...

  10. C++中的三种继承方式

    1,被忽略的细节: 1,冒号( :)表示继承关系,Parent 表示被继承的类,public 的意义是什么? class Parent { }; class Child : public Parent ...

随机推荐

  1. windows_exporter 安装

    windows_exporter 安装 背景 如果想使用Prometheus监控Windows主机相关参数,那么就需要在Windows系统的主机上进行安装指标收集器. windows_exporter ...

  2. 49从零开始用Rust编写nginx,我竟然在同一个端口上绑定了多少IP

    wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 负载均衡, 静态文件服务器,websocket代理,四层TCP/UDP转发,内网穿透等,会将实 ...

  3. axios.delete传参,400错误

    我在使用axios.delete进行传参的时候,发现会报400错误 后端代码(C#) 前端代码 这样的参数请求会报400错误 后端就一个参数,前端发一个id为什么接受不到呢? 在网上找了半天,终于明白 ...

  4. NC16562 [NOIP2012]开车旅行

    题目链接 题目 题目描述 小 A 和小 B 决定利用假期外出旅行,他们将想去的城市从 1 到 N 编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市 i 的海拔高度为 ...

  5. NC16129 小小粉刷匠

    题目链接 题目 题目描述 "lalala,我是一个快乐的粉刷匠",小名一边快活地唱着歌,一边开心地刷着墙",兴致突然被打断,"小名,你今天如果刷不完这一栋楼的墙 ...

  6. SpringBoot+Shiro+LayUI权限管理系统项目-1.项目介绍

    1.项目介绍 本项目旨在打造一个基于RBAC架构模式的通用的.并不复杂但易用的权限管理系统.通过本项目可以较好的理解权限系统的常见业务同时学习掌握Springboot和Shiro等诸多技术点.需要的朋 ...

  7. Java并发编程实例--6.线程的join方法

    有时我们需要等到某个线程执行完毕.例如,我可能有一个线程来初始化资源完毕然后其他线程才能开始执行. 谓词,我们可以使用Thread类的join()方法. 本例中,我们将学习使用这个方法. DataSo ...

  8. C++ { } 的使用场景

    {} 可以用于初始化 C++11 中的变量,就像它们用于初始化 C 中的数组和结构一样. {} 主要是为了提供语法的一致性(使用 {} 初始化将在所有上下文中都有效,而使用赋值运算符或()初始化将在特 ...

  9. 使用GDI时如何确定是否有内存泄漏

    在创建GDI对象时,比如创建笔,画刷等对象时,在调用完之后忘记删除对象了,会造成内存泄漏 我们可以通过任务管理器来快速的查看 启动任务管理器(右键单击Windows任务栏以选择任务管理器) 在Wind ...

  10. HTML学习---day01

    1.head标签 <!DOCTYPE html> <!--文档声明H5 html--> <html lang="en"> <head> ...