C++类基础(十七)
类的继承——补充知识
● public 与 private 继承(C++ Public, Protected and Private Inheritance)
改变了类所继承的成员的访问权限
//公有继承
struct Base
{
public:int x;
private:int y;
protected:int z;
};
struct Derive : public Base //公有继承基类
{
/*public:int x;
protected:int z;*/void fun(){x = 10; //可以访问,公有继承基类后,基类中的公有成员在派生类中的访问权限仍然是公有成员y = 11; //不可访问,无论哪种继承基类,基类的私有成员只能在基类中访问 Error: 'y' is a private member of 'Base'z = 12; //可以访问,公有继承基类后,基类中的保护成员在派生类中的访问权限仍然是保护成员}
};
struct Derive2 : public Derive //公有继承派生类
{void fun(){x = 10; //可以访问,公有继承派生类后,基类中的公有成员在派生类的派生类中的访问权限仍然是公有成员y = 11; //不可访问,无论哪种继承派生类,基类的私有成员只能在基类中访问 Error: 'y' is a private member of 'Base'z = 12; //可以访问,公有继承派生类后,基类中的保护成员在派生类的派生类中的访问权限仍然是保护成员}
};
int main()
{Base val;val.x; //类外可以访问该类的公有成员val.y; //类外不能访问该类的私有成员, Error: 'y' is a private member of 'Base'val.z; //类外不能访问该类的保护成员, Error: 'z' is a protected member of 'Base'Derive d;d.x; //派生类对象可以在类外访问基类的公有成员d.y; //派生类对象不可在类外访问基类的私有成员,Error: 'y' is a private member of 'Base'd.z; //派生类对象不可在类外访问基类的保护成员,Error: 'z' is a protected member of 'Base'Derive2 d2;d2.x; //派生类的派生类对象可以在类外访问基类的公有成员d2.y; //派生类的派生类对象不可在类外访问基类的私有成员,Error: 'y' is a private member of 'Base'd2.z; //派生类的派生类对象不可在类外访问基类的保护成员,Error: 'z' is a protected member of 'Base'
}
//保护继承
struct Base
{
public:int x;
private:int y;
protected:int z;
};
struct Derive : protected Base //保护继承基类
{
/*protected:int x;
protected:int z;*/void fun(){x = 10; //可以访问,保护继承基类后,基类中的保护成员在派生类中的访问权限成为保护成员y = 11; //不可访问,无论哪种继承基类,基类的私有成员只能在基类中访问 Error: 'y' is a private member of 'Base'z = 12; //可以访问,保护继承基类后,基类中的保护成员在派生类中的访问权限仍然是保护成员}
};
struct Derive2 : public Derive //公有继承派生类
{void fun(){x = 10; //可以访问,公有继承派生类后,基类中的公有成员在经过派生类的保护继承后变成保护成员,在派生类的派生类中仍是保护成员y = 11; //不可访问,无论哪种继承派生类,基类的私有成员只能在基类中访问 Error: 'y' is a private member of 'Base'z = 12; //可以访问,公有继承派生类后,基类中的保护成员在派生类的派生类中的访问权限仍然是保护成员}
};
int main()
{Base val;val.x; //类外可以访问该类的公有成员val.y; //类外不能访问该类的私有成员, Error: 'y' is a private member of 'Base'val.z; //类外不能访问该类的保护成员, Error: 'z' is a protected member of 'Base'Derive d;d.x; //基类中的公有成员在经过派生类的保护继承后变成派生类的保护成员,派生类对象不可在类外访问自己的保护成员,Error: 'x' is a protected member of 'Base'd.y; //派生类对象不可在类外访问基类的私有成员,Error: 'y' is a private member of 'Base'd.z; //保护继承对基类的保护成员的访问权限无影响,派生类对象不可在类外访问基类的保护成员,Error: 'z' is a protected member of 'Base'Derive2 d2;d2.x; //基类中的公有成员在经过派生类的保护继承后变成派生类的保护成员,派生类的派生类对象不可在类外访问该保护成员,Error: 'x' is a protected member of 'Base'd2.y; //派生类的派生类对象不可在类外访问基类的私有成员,Error: 'y' is a private member of 'Base'd2.z; //保护继承对基类的保护成员的访问权限无影响,派生类的派生类对象不可在类外访问该保护成员,Error: 'z' is a protected member of 'Base'
}
//私有继承
struct Base
{
public:int x;
private:int y;
protected:int z;
};
struct Derive : private Base //私有继承基类
{
/*private:int x;
private:int z;*/void fun(){x = 10; //可以访问,私有继承基类后,基类中的保护成员在派生类中的访问权限成为私有成员y = 11; //不可访问,无论哪种继承基类,基类的私有成员只能在基类中访问 Error: 'y' is a private member of 'Base'z = 12; //可以访问,私有继承基类后,基类中的保护成员在派生类中的访问权限成为私有成员}
};
struct Derive2 : public Derive //公有继承派生类
{void fun(){x = 10; //不可访问,公有继承派生类后,基类中的公有成员在经过派生类的私有继承后变成私有成员,在派生类的派生类中已不可见,Error: 'x' is a private member of 'Base'y = 11; //不可访问,无论哪种继承派生类,基类的私有成员只能在基类中访问,Error: 'y' is a private member of 'Base'z = 12; //不可访问,公有继承派生类后,基类中的保护成员在经过派生类的私有继承后变成私有成员,在派生类的派生类中已不可见,Error: 'z' is a private member of 'Base'}
};
int main()
{Base val;val.x; //类外可以访问该类的公有成员val.y; //类外不能访问该类的私有成员, Error: 'y' is a private member of 'Base'val.z; //类外不能访问该类的保护成员, Error: 'z' is a protected member of 'Base'Derive d;d.x; //基类中的公有成员在经过派生类的私有继承后变成派生类的私有成员,派生类对象不可在类外访问自己的私有成员,Error: 'x' is a private member of 'Base'd.y; //派生类对象不可在类外访问基类的私有成员,Error: 'y' is a private member of 'Base'd.z; //基类中的保护成员在经过派生类的私有继承后变成派生类的私有成员,派生类对象不可在类外访问自己的私有成员,Error: 'z' is a private member of 'Base'Derive2 d2;d2.x; //基类中的公有成员在经过派生类的保继承后变成派生类的私有成员,派生类的派生类对象不可在类外访问该私有成员,Error: 'x' is a private member of 'Base'd2.y; //派生类的派生类对象不可在类外访问基类的私有成员,Error: 'y' is a private member of 'Base'd2.z; //基类中的保护成员在经过派生类的私有继承后变成派生类的私有成员,派生类的派生类对象不可在类外访问该私有成员,Error: 'z' is a private member of 'Base'
}
– public 继承:描述 是一个 的关系 “ ”
– private 继承:描述 根据基类实现出 的关系 “ ”
– protected 继承:几乎不会使用
● using 与继承
– 使用 using 改变基类成员的访问权限
● 派生类可以访问该成员
struct Base
{
public:int x = 10;
private:int y = 20;
protected:int z = 30;
};
struct Derive : Base
{
public:using Base::z; //在派生类中使用using改变了基类成员的访问权限,using只能改变在派生类中可见的基类成员的访问权限(即公有成员和保护成员)using Base::y; //基类的私有成员在基类外都是不可见的,因此不能使用using改变基类私有成员的访问权限, Error: 'y' is a private member of 'Base'
};
int main()
{Derive d;std::cout << d.x << '\n'; //Of course OKstd::cout << d.z << '\n'; //OK
}
● 无法改变构造函数的访问权限
struct Base
{
protected:Base(int) {}
};
struct Derive : Base
{
public:using Base::Base; //Error: 'Base(int)' is protected within this context
};
struct Base
{
protected:void fun(){std::cout << "void fun()\n";}void fun(int input){std::cout << "void fun(int input): " << input << '\n';}void fun(char ch){std::cout << "void fun(char ch): " << ch << '\n';}
};
struct Derive : Base
{
public:using Base::fun; //同时改变基类中重载的三个fun()的权限
};
int main()
{Derive d;d.fun(); //OKd.fun(3); //OKd.fun('a'); //OK
}
struct Base
{
protected:void fun(){std::cout << "void Base::fun()\n";}void go(){std::cout << "void Base::go()\n";}
};
struct Derive : private Base
{
public:using Base::fun; //私有继承后,Base::fun()在派生类中成为私有成员,使用using改变其成为公有成员void go2(){std::cout << "void Derive::go2()\n";go();}
};
int main()
{Derive d;d.fun();d.go2();
}
– 使用 using 继承基类的构造函数逻辑
struct Base
{
public:Base(int) //公有成员{std::cout << "Base(int)\n";}
};
struct Derive : Base
{
public:using Base::Base;
};
int main()
{Derive d(10);
}
struct Base
{
public:Base(int){std::cout << "Base(int)\n";}
};
struct Derive : Base
{
public:Derive(int x): Base(x) //对基类构造函数的增删改会影响到派生类构造函数的增删改,维护极其不便{}using Base::Base; //使用using
};
– using 与部分重写
struct Base
{
protected:virtual void fun(){std::cout << "virtual void fun()\n";}virtual void fun(int){std::cout << "virtual void fun(int)\n";}
};
struct Derive : Base
{
public:using Base::fun;
};
int main()
{Derive d;d.fun();d.fun(100);
}
struct Base
{
protected:virtual void fun(){std::cout << "virtual void Base::fun()\n";}virtual void fun(int){std::cout << "virtual void Base::fun(int)\n";}
};
struct Derive : Base
{
public:using Base::fun;void fun(int) override{std::cout << "void Derive::fun(int) override\n";}
};
int main()
{Derive d;d.fun();d.fun(100);
}
struct Base
{
protected:Base(int) = default; //保护成员,Error: Only special member functions may be defaulted
};
struct Derive : Base
{
public:using Base::Base;
};
int main()
{Derive d(10); //Error: Calling a protected constructor of class 'Base'
}
struct Base
{
protected:Base() = default; //OK,编译器为Base合成了一个缺省构造函数,权限为public,供外界使用
};
struct Derive : Base
{
};
int main()
{Derive d; //OK
}
● 继承与友元:友元关系无法继承,但基类的友元可以访问派生类中基类的相关成员
//基类的友元
struct Base
{friend void fun(const Base&); //fun是Base的友元
public:int x;
private:int y;
protected:int z;
};
struct Derive : Base
{
private:int xxx;
};
void fun(const Base& b)
{b.x; //OKb.y; //OKb.z; //OKconst auto& d = static_cast<const Derive&>(b);d.xxx; //fun是Base的友元,Derive派生自Base,但fun并不是Derive的友元
}
//派生类的友元
struct Base
{
public:int x;
private:int y;
protected:int z;
};
struct Derive : Base
{friend void fun(const Derive&); //fun是Derive的友元
private:int xxx;
};
void fun(const Derive& d)
{d.x; //fun是Derive的友元,可以访问Derive中所有可见的基类成员d.y; //不可访问,Error: 'y' is a private member of 'Base',d.z; //fun是Derive的友元,可以访问Derive中所有可见的基类成员d.xxx; //fun是Derive的友元,可以访问Derive的所有成员
}
参考
深蓝学院: C++基础与深度解析
C++ Public, Protected and Private Inheritance
相关文章:

C++类基础(十七)
类的继承——补充知识 ● public 与 private 继承(C Public, Protected and Private Inheritance) 改变了类所继承的成员的访问权限 //公有继承 struct Base { public:int x; private:int y; protected:int z; }; struct Derive : public Base //公有继承…...

LeetCode刷题复盘笔记—一文搞懂贪心算法之56. 合并区间(贪心算法系列第十四篇)
今日主要总结一下可以使用贪心算法解决的一道题目,56. 合并区间 题目:56. 合并区间 Leetcode题目地址 题目描述: 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间…...

Andriod入门级开发
这学期有个课设,我们组我负责一个手机APP的开发,虽然刚开始说要实现什么智能导航,类似高德地图那种,但最后阉割的只剩一个Socket通信了,因为之前没有接触过(可能之后也不会再接触),记…...

DCL 数据控制语言
1、简介 DCL英文全称是Data Control Language(数据控制语言),用来管理数据库用户、控制数据库的访问权限。 2、管理用户 2.1 查询用户 select * from mysql.user;查询的结果如下: 其中 Host代表当前用户访问的主机, 如果为localhost, 仅代表只能够在当前本机访问…...

全网超详细的下载与安装VMware虚拟机以及为什么要安装VMware虚拟机
文章目录1. 文章引言2. 下载VMware3. 安装VMware1. 文章引言 我们使用最多的系统是windows系统,因为,国内电脑厂商的操作系统(os)基本是windows系统,比如华为、联想、华硕等电脑。 但线上的服务器大多是Linux系统,而我们经常使用…...

Python获取zabbix问题触发器
背景:阿里云的ECS服务器因为阿里云升级插件,导致安全防护程序重启,产生不同的端口。导致低自动发现注册的端口 大量报警。 解决:杀掉关于因为非业务 变更的端口检测的触发器。 相关文档: Zabbix监控之主机端口监控自…...

原型链污染
目录 前置知识 原型对象 prototype和__proto__的区别 原型链概念 原型链的继承 原型 链污染 原型链污染原理 javascript中可能会存在原型链污染的危险函数 原型链污染的实际应用 JavaScript中可以触发弹窗的函数 前置知识 原型对象 在JavaScript中,每个函…...
ClickHouse详解
一、概念ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。OLAP场景的关键特征绝大多数是读请求数据以相当大的批次(> 1000行)更新,而不是单行更新;或者根本没有更新。已添加到数据库的数据不能修改。对于读取,从数据库中提取相当多的…...
02_Docker 安装
02_Docker 安装 文章目录02_Docker 安装2.1 安装 Docker 的先决条件2.2 在 Ubuntu 和 Debain 中安装 Docker2.2.1 检查前提条件1. 内核2.检查 Device Manager2.2 安装 DockerDocker 支持非常多的Linux平台,包括Ubuntu和RHEL,除此之外,Docker还…...

K8S集群将Docker切换到Containerd
文章目录1. 开启节点维护1.1 将节点设置成不可调度1.2 驱逐节点上的 Pod1.3 停止相关服务2. 升级到 containerd2.1 安装 containerd2.2 调整 containerd 配置2.3 修改 kubelet 启动配置参数3. 重启节点服务4. 验证升级后的节点5. 容器管理工具5.1 容器管理命令行工具对比5.2 cr…...

Kubernetes03:kubernetes 功能和架构
2.1 概述 Kubernetes 是一个轻便的和可扩展的开源平台,用于管理容器化应用和服务。通过 Kubernetes 能够进行应用的自动化部署和扩缩容。在 Kubernetes 中,会将组成应用的容 器组合成一个逻辑单元以更易管理和发现。Kubernetes 积累了作为 Google 生产环…...

LabVIEW中CPU和内存使用情况在NI分布式系统管理器中不可见
LabVIEW中CPU和内存使用情况在NI分布式系统管理器中不可见想使用NI分布式系统管理器监测网络连接实时控制器的CPU和内存使用情况。从左侧窗口的树中选择了感兴趣的实时目标,然后通过选择视图自动视图来确保启用自动查看。希望看到CPU/内存选项卡,但它有显…...

buu [NPUCTF2020]Classical Cipher 1
题目描述: 题目分析: 首先输入密码 {gsv_pvb_rh_zgyzhs} 后,得到:可以得知密码是错误的,再看看密码 {gsv_pvb_rh_zgyzhs} ,排列无序,那么尝试用凯撒与栅栏解密,发现还是解不出&…...

分享96个HTML体育竞技模板,总有一款适合您
分享96个HTML体育竞技模板,总有一款适合您 96个HTML体育竞技模板下载链接:https://pan.baidu.com/s/1k2vJUlbd2Boduuqqa0EWMA?pwdj8ji 提取码:j8ji Python采集代码下载链接:采集代码.zip - 蓝奏云 北京奥运火炬PSD模板 奥运…...

Python pandas「原有或者新建」Excel中「追加新或者新建」sheet
1.pandas原有Excel中追加新sheet 使用Pandas库,我们可以轻松将数据追加到现有的Excel工作簿中的新工作表中。以下是追加新工作表的简单步骤: 读取现有的Excel文件 使用Pandas库中的read_excel()函数读取现有的Excel文件。指定Excel文件的路径和文件名&a…...
程序员必备的软技能- CPU“没有灵魂的躯体”
引言 先引用一段比较有意思的论述: 现实中每个人是由两部分构成,灵魂和躯体,灵魂依附于躯体游走于世间,现实中我们面对的每个人其实面对的是其灵魂而非肉体,肉体不过是表象而已。 灵魂本性乃一恶物,寄生于…...

基于微信小程序的青少年生理健康知识小助手
基于微信小程序的青少年生理健康知识小助手 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目…...

【scl】博图程序的导入和导出
导入或者导出博图文件的方法(也叫移植文件) 目录 前言 编辑 编辑 前言 本篇文章主要写一下关于博图文件的导入和导出,具体要怎么样才能将写好的程序或者块移植到其他地方,下面我们一起来看! 一、程序块的导入和导…...

【C语言】指针进阶
目录 一、字符指针 二、指针数组 三、数组指针 四、数组指针的使用 五、函数指针数组 六、指向函数指针数组的指针 七、回调函数 我们知道了指针的概念: 1. 指针就是个变量,用来存放地址,地址唯一标识一块内存空间。 2. 指针的大小是…...

18:CTK 总结篇(FAQ)
作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 经过了几个月的艰苦奋战,终于到了最后一节啦,是不是和我一样,心里有点儿小激动! 回顾之前的章节,从初级 -> 进阶 -> 高级,我们针对 CTK 做了详细的分类讲解。希望通过这些知识,大家能对模块化…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...