掘根宝典之C++包含对象的类,私有继承,保护继承,三大继承方式总结
包含对象成员的类
包含,组合和层次化:一个类里面的类成员之一是个类对象
我们来看个例子
#include<iostream>
using namespace std;
class AA
{
private:int a_;
public:AA(int a):a_(a){}void A(){cout << a_ << endl;}
};
class BB
{
private:AA t;int b_;
public:BB(int a,int b):t(a),b_(b){}void B(){t.a_ = 9;//不可以,a_是AA类的私有成员,在BB类无法直接使用t = { 9 };//可以cout << b_ << endl;t.A();//可以直接调用AA类的公有函数}
};
int main()
{BB t(2, 3);t.B();
}
这里的访问权限可能会让大家有一点绕。实际上并没有。
我们把AA类视为类,把BB类视为main函数,这样子BB类对AA类的访问权限就明白了。
私有继承
在C++中,私有继承是一种继承方式,它定义了一个私有派生类,也称为派生类。私有继承意味着派生类继承了基类的所有成员,但这些成员在派生类中是私有的,对外部不可见。
要进行私有继承请使用private关键字,或者不使用任何关键字(因为private是默认值,因此省略访问限定符也将导致私有继承)
格式如下
class 派生类名:private 基类名
{
}或者class 派生类名:基类名
{
}
使用私有继承时,只能在派生类的方法里使用基类的方法
私有继承允许使用类名和作用域解析运算符来调用基类的方法
我们看个例子
#include<iostream>
using namespace std;
class AA
{
private:int a_;
public:AA(int a):a_(a){}void A(){cout << a_ << endl;}
};
class BB :AA
{
private:int b_;
public:BB(int a,int b):AA(a),b_(b){}void B(){A();//可以AA::A();//可以}
};int main()
{BB r(2, 3);r.B();}
我们怎么通过派生类访问基类对象呢?当然是用强制类型转换
我们看个例子
#include<iostream>
using namespace std;
class AA
{
private:int a_;
public:AA(int a):a_(a){}void A(){cout << a_ << endl;}
};
class BB :AA
{
private:int b_;
public:BB(int a,int b):AA(a),b_(b){}AA& B(){return (AA&)*this;//派生类强制转换为基类}
};int main()
{BB r(2, 3);AA t=r.B();t.A();}
在私有继承中,未进行显式类型转换的派生类引用或指针,无法赋值给基类的引用或指针
#include<iostream>
using namespace std;
class AA
{
private:int a_;
public:AA(int a):a_(a){}void A(){cout << a_ << endl;}
};
class BB :AA
{
private:int b_;
public:BB(int a,int b):AA(a),b_(b){}};int main()
{BB r(2, 3);AA& t = r;//这是不行的AA* y = &r;//这是不行的
}
保护继承
保护继承是私有继承的变体。保护继承在列出基类时使用关键字protected:
class 派生类名:protected 基类名
{
}
使用保护继承时,基类的公有成员和保护成员都成为派生类的保护成员。和私有继承一样,基类的接口在派生类中也是可用的,但是在继承层次结构之外是不可用的。当从派生类派生出另一个类时,私有继承和保护继承的区别就体现出来了。使用私有继承时,第三代类将不能使用基类的接口,这是因为基类的公有方法在派生类中变成私有方法;使用保护继承时,基类的公有方法在第二代中变成受保护的,因此第三代派生类可以使用它们。
三种继承方式的比较
公有继承(public)继承、私有继承(private)、保护继承(protected)是常用的三种继承方式。
1.公有继承(public)
公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的,不能被这个派生类的子类所访问。
2.私有继承(private)
私有继承的特点是基类的公有成员和保护成员都作为派生类的私有成员,并且不能被这个派生类的子类所访问。
3.保护继承
保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。
三种不同继承方式的基类特性和派生类特性
公有继承 | 保护继承 | 私有继承 | |
公有成员变为 | 派生类的公有成员 | 派生类的保护成员 | 派生类的私有成员 |
保护成员变成 | 派生类的保护成员 | 派生类的保护成员 | 派生类的私有成员 |
私有成员变为 | 只能通过基类接口访问 | 只能通过基类接口访问 | 只能通过基类接口访问 |
能否隐式向上转换 | 是 | 是(但只能在基类里) | 否 |
注:隐式向上转换:意味着无需进行显式类型转换,就可以将基类指针或引用指向派生类对象
在上图中:
1.基类成员对派生类都是:public和protected的成员是可见的,private的成员是不可见的。
2.基类成员对派生类的对象来说:要看基类的成员在派生类中变成了什么类型的成员。如:私有继承时,基类的公有成员和私有成员都变成了派生类中的私有成员,因此对于派生类中的对象来说基类的公有成员和私有成员就是不可见的。为了进一步理解三种不同的继承方式在其成员的可见性方面的区别,下面从三种不同角度进行讨论。
对于公有继承方式
1.基类成员对其对象的可见性:公有成员可见,其他不可见。这里保护成员同于私有成员。
2.基类成员对派生类的可见性:公有成员和保护成员可见,而私有成员不可见。这里保护成员同于公有成员。
3.基类成员对派生类对象的可见性:公有成员可见,其他成员不可见。
所以:在公有继承时,派生类的对象可以访问基类中的公有成员;派生类的成员函数可以访问基类中的公有成员和保护成员。这里,一定要区分清楚派生类的对 象和派生类中的成员函数对基类的访问是不同的。
对于私有继承方式
1.基类成员对其对象的可见性:公有成员可见,其他成员不可见
2.基类成员函数对派生类的可见性:公有成员和保护成员是可见的,而私有成员是不可见的。
3.基类成员对派生类对象的可见性:所有成员都是不可见的。
所以:在私有继承时,基类的成员只能由直接派生类访问,而无法向下继承。
对于保护继承方式
这种继承方式与私有继承方式的情况相同。两者的区别仅在于对派生类的成员而言,而对于基类成员有不同的可见性。(可见性也就是可访问性)。
关于可访问性还有另外一种说法。这种规则中,称派生类的对象对基类访问为水平访问,称派生类的派生类对基类的访问为垂直访问。
1 #include<iostream>2 class A{3 private:4 int privatedataA;5 protected:6 int protecteddataA;7 public:8 int publicdataA;9 };
10 //基类A的派生类B(公有继承)
11 class B :public A{
12
13 public:
14 void funcA()
15 {
16 int b;
17 b = privatedataA;
18 //错误:基类中的私有成员在派生类中不可见
19 b = protecteddataA;
20 //正确:基类的保护成员在派生类中是保护成员
21 b = publicdataA;
22 //正确:基类的公共成员在派生类是公共成员
23 }
24 };
25 //基类A的派生类C 私有继承
26 class C :private A{
27
28 public:
29 void funcA()
30 {
31 int c;
32 c = privatedataA;
33 //错误:基类中的私有成员在派生类中不可见
34 c = protecteddataA;
35 //正确:基类的保护成员在派生类中是私有成员
36 c = publicdataA;
37 //正确:基类的公共成员在派生类是私有成员
38 }
39 };
40 //基类A的派生类D 保护继承
41 class D :protected A{
42 public:
43 void funcA()
44 {
45 int d;
46 d = privatedataA;
47 //错误:基类中的私有成员在派生类中不可见
48 d = protecteddataA;
49 //正确:基类的保护成员在派生类中是保护成员
50 d = publicdataA;
51 //正确:基类的公共成员在派生类是保护成员
52 }
53 };
54 void main()
55 {
56 int value;
57 B objB;
58 value = objB.privatedataA;//错误:基类的私有成员在派生类不可见,对对象不可见
59 value = objB.protecteddataA;//错误:基类的保护成员在派生类中是保护成员,对对象不可见
60 value = objB.publicdataA;//错误:基类的公共成员在派生类中是公共成员,对对象可见
61
62 C objC;
63 value = objC.privatedataA;//错误:基类的私有成员在派生类不可见,对对象不可见
64 value = objC.protecteddataA;//错误:基类的保护成员在派生类中是私有成员,对对象不可见
65 value = objC.publicdataA;//错误:基类的公共成员在派生类中是私有成员,对对象不可见
66
67 D objD;
68 value = objD.privatedataA;//错误:基类的私有成员在派生类不可见,对对象不可见
69 value = objD.protecteddataA;//错误:基类的保护成员在派生类中是保护成员,对对象不可见
70 value = objD.publicdataA;//错误:基类的公共成员在派生类中是保护成员,对对象不可见
71 system("pause");
72 }
相关文章:
掘根宝典之C++包含对象的类,私有继承,保护继承,三大继承方式总结
包含对象成员的类 包含,组合和层次化:一个类里面的类成员之一是个类对象 我们来看个例子 #include<iostream> using namespace std; class AA { private:int a_; public:AA(int a):a_(a){}void A(){cout << a_ << endl;} }; class …...

第六篇:MySQL图形化管理工具
经过前五篇的学习,对于数据库这门技术的理解,我们已经在心中建立了一个城堡大致的雏形,通过命令行窗口(cmd)快速上手了【SQL语法-DDL-数据定义语言】等相关命令 道阻且长,数据库技术这一宝藏中还有数不清的…...

计算机网络——12DNS
DNS DNS的必要性 IP地址标识主机、路由器但IP地址不好记忆,不便于人类用使用(没有意义)人类一般倾向于使用一些有意义的字符串来标识Internet上的设备存在着“字符串”——IP地址的转换的必要性人类用户提供要访问机器的“字符串”名称由DN…...

vue3-应用规模化-工具链
工具链 项目脚手架 Vite Vite 是一个轻量级的、速度极快的构建工具,对 Vue SFC 提供第一优先级支持。作者是尤雨溪,同时也是 Vue 的作者! 要使用 Vite 来创建一个 Vue 项目,非常简单: (推荐)…...

EasyExcel动态列导出
测试代码地址:https://gitee.com/wangtianwen1996/cento-practice/tree/master/src/test/java/com/xiaobai/easyexcel/dynamiccolumn 官方文档:https://easyexcel.opensource.alibaba.com/docs/2.x/quickstart/write 一、实现方式 1、根据需要导出的列…...
JAVA面试题11
什么是Java的访问修饰符,并列出它们的作用。 Java的访问修饰符包括public、private、protected和默认。它们的作用如下: public: 可以被任何其他类访问。 private: 只能被所在类访问,其他类无法访问。 protected: 可以被所在类和同一个包中的…...

工业数据采集的时间不确定性及PLC-Recorder的通道偏移功能
目录 一、缘起 二、效果展示 三、设置方法 四、小结 一、缘起 大家都知道采集软件首先要尽可能还原数据原来的状态,给用户提供一个可以信赖的参考。但是,数据采集又有很多随机因素:Windows是一个周期不严格的系统、以太网通讯有时间波动、…...

十五、Object 类
文章目录 Object 类6.1 public Object()6.2 toString方法6.3 hashCode和equals(Object)6.4 getClass方法6.5 clone方法6.6 finalize方法 Object 类 本文为书籍《Java编程的逻辑》1和《剑指Java:核心原理与应用实践》2阅读笔记 java.lang.Object类是类层次结构的根…...

计算机网络——06分组延时、丢失和吞吐量
分组延时、丢失和吞吐量 分组丢失和延时是怎样发生的 在路由器缓冲区的分组队列 分组到达链路的速率超过了链路输出的能力分组等待排到队头、被传输 延时原因: 当当前链路有别的分组进行传输,分组没有到达队首,就会进行排队,从…...

[C#] 如何调用Python脚本程序
为什么需要C#调用python? 有以下几个原因需要C#调用Python: Python拥有丰富的生态系统:Python有很多强大的第三方库和工具,可以用于数据科学、机器学习、自然语言处理等领域。通过C#调用Python,可以利用Python的生态系…...

AlmaLinux更换鼠标样式为Windows样式
文章目录 前言先看看条件与依赖第一步:测试最终效果第二步:使用CursorXP修改鼠标样式CurosrXP安装CursorXP使用 第三步:Linux端环境搭建与命令执行UbuntuFedora其他系统均失败 第四步:应用主题 前言 只不过是突发奇想,…...

BUGKU-WEB 留言板
题目描述 题目无需登录后台!需要xss平台接收flag, http协议需要http协议的xss平台打开场景后界面如下: 解题思路 看到此类的题目,应该和存储型xss有关,也就是将恶意代码保存到服务器端即然在服务器端,那就…...

Linux之动静态库
今天我们来讲动静态库! 首先我们来粗粒度的划分一下动态库和静态库。 动态库就是只有一份库文件,所有想用该库的文件与改库文件建立链接,然后使用。这样可以提高代码复用率,避免重复拷贝产生没必要的内存消耗。 静态库…...
手机常亮屏不自动灭屏
一. 基础知识介绍 1. WakeLock(休眠锁) WakeLock用于保持设备的唤醒状态,有些情况下,即时用户不操作App,我们也需要保持屏幕处于唤醒状态,以保证用户体验,比如视频类APP和计步类APP,…...

JVM(1)基础篇
1 初始JVM 1.1 什么是JVM JVM 全称是 Java Virtual Machine,中文译名 Java虚拟机。JVM 本质上是一个运行在计算机上的程序,他的职责是运行Java字节码文件。 Java源代码执行流程如下: 分为三个步骤: 编写Java源代码文件。 使用…...

相机图像质量研究(12)常见问题总结:光学结构对成像的影响--炫光
系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结:光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结:光学结构对成…...

[OPEN SQL] 删除数据
DELETE语句用于删除数据库表中的数据 本次操作使用的数据库表为SCUSTOM,其字段内容如下所示 航班用户(SCUSTOM) 需要删除以下数据 1.删除单条数据 语法格式 DELETE <dbtab> FROM <wa>. DELETE <dbtab> FROM TABLE <itab>. DELETE FROM &…...

C语言第二十五弹---字符函数和字符串函数(上)
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】 目录 1、字符分类函数 2、字符转换函数 3、strlen的使用和模拟实现 4、strcpy 的模拟实现 5、strcat 的模拟实现 6、strcmp 的模拟实现 7、strncpy 函数的使用 总结…...
寒假学习记录16:Express框架(Node)
后续会补充 1.引入express 1.先下载express框架 创建一个package.json格式的文件,里面写入 {"dependencies": {"express": "~4.16.1" //express版本号} } 然后打开终端输入 npm i 2.引入express模块 const express require(&quo…...

机器学习中的10种非线性降维技术对比总结
降维意味着我们在不丢失太多信息的情况下减少数据集中的特征数量,降维算法属于无监督学习的范畴,用未标记的数据训练算法。 尽管降维方法种类繁多,但它们都可以归为两大类:线性和非线性。 线性方法将数据从高维空间线性投影到低维空间(因此…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...
多元隐函数 偏导公式
我们来推导隐函数 z z ( x , y ) z z(x, y) zz(x,y) 的偏导公式,给定一个隐函数关系: F ( x , y , z ( x , y ) ) 0 F(x, y, z(x, y)) 0 F(x,y,z(x,y))0 🧠 目标: 求 ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z、 …...