当前位置: 首页 > news >正文

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 继承&#xff08;C Public, Protected and Private Inheritance&#xff09; 改变了类所继承的成员的访问权限 //公有继承 struct Base { public:int x; private:int y; protected:int z; }; struct Derive : public Base //公有继承…...

LeetCode刷题复盘笔记—一文搞懂贪心算法之56. 合并区间(贪心算法系列第十四篇)

今日主要总结一下可以使用贪心算法解决的一道题目&#xff0c;56. 合并区间 题目&#xff1a;56. 合并区间 Leetcode题目地址 题目描述&#xff1a; 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间…...

Andriod入门级开发

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

DCL 数据控制语言

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

全网超详细的下载与安装VMware虚拟机以及为什么要安装VMware虚拟机

文章目录1. 文章引言2. 下载VMware3. 安装VMware1. 文章引言 我们使用最多的系统是windows系统&#xff0c;因为&#xff0c;国内电脑厂商的操作系统(os)基本是windows系统&#xff0c;比如华为、联想、华硕等电脑。 但线上的服务器大多是Linux系统&#xff0c;而我们经常使用…...

Python获取zabbix问题触发器

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

原型链污染

目录 前置知识 原型对象 prototype和__proto__的区别 原型链概念 原型链的继承 原型 链污染 原型链污染原理 javascript中可能会存在原型链污染的危险函数 原型链污染的实际应用 JavaScript中可以触发弹窗的函数 前置知识 原型对象 在JavaScript中&#xff0c;每个函…...

ClickHouse详解

一、概念ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。OLAP场景的关键特征绝大多数是读请求数据以相当大的批次(> 1000行)更新&#xff0c;而不是单行更新;或者根本没有更新。已添加到数据库的数据不能修改。对于读取&#xff0c;从数据库中提取相当多的…...

02_Docker 安装

02_Docker 安装 文章目录02_Docker 安装2.1 安装 Docker 的先决条件2.2 在 Ubuntu 和 Debain 中安装 Docker2.2.1 检查前提条件1. 内核2.检查 Device Manager2.2 安装 DockerDocker 支持非常多的Linux平台&#xff0c;包括Ubuntu和RHEL&#xff0c;除此之外&#xff0c;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 是一个轻便的和可扩展的开源平台&#xff0c;用于管理容器化应用和服务。通过 Kubernetes 能够进行应用的自动化部署和扩缩容。在 Kubernetes 中&#xff0c;会将组成应用的容 器组合成一个逻辑单元以更易管理和发现。Kubernetes 积累了作为 Google 生产环…...

LabVIEW中CPU和内存使用情况在NI分布式系统管理器中不可见

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

buu [NPUCTF2020]Classical Cipher 1

题目描述&#xff1a; 题目分析&#xff1a; 首先输入密码 {gsv_pvb_rh_zgyzhs} 后&#xff0c;得到&#xff1a;可以得知密码是错误的&#xff0c;再看看密码 {gsv_pvb_rh_zgyzhs} &#xff0c;排列无序&#xff0c;那么尝试用凯撒与栅栏解密&#xff0c;发现还是解不出&…...

分享96个HTML体育竞技模板,总有一款适合您

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

Python pandas「原有或者新建」Excel中「追加新或者新建」sheet

1.pandas原有Excel中追加新sheet 使用Pandas库&#xff0c;我们可以轻松将数据追加到现有的Excel工作簿中的新工作表中。以下是追加新工作表的简单步骤&#xff1a; 读取现有的Excel文件 使用Pandas库中的read_excel()函数读取现有的Excel文件。指定Excel文件的路径和文件名&a…...

程序员必备的软技能- CPU“没有灵魂的躯体”

引言 先引用一段比较有意思的论述&#xff1a; 现实中每个人是由两部分构成&#xff0c;灵魂和躯体&#xff0c;灵魂依附于躯体游走于世间&#xff0c;现实中我们面对的每个人其实面对的是其灵魂而非肉体&#xff0c;肉体不过是表象而已。 灵魂本性乃一恶物&#xff0c;寄生于…...

基于微信小程序的青少年生理健康知识小助手

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

【scl】博图程序的导入和导出

导入或者导出博图文件的方法&#xff08;也叫移植文件&#xff09; 目录 前言 ​编辑 ​编辑 前言 本篇文章主要写一下关于博图文件的导入和导出&#xff0c;具体要怎么样才能将写好的程序或者块移植到其他地方&#xff0c;下面我们一起来看&#xff01; 一、程序块的导入和导…...

【C语言】指针进阶

目录 一、字符指针 二、指针数组 三、数组指针 四、数组指针的使用 五、函数指针数组 六、指向函数指针数组的指针 七、回调函数 我们知道了指针的概念&#xff1a; 1. 指针就是个变量&#xff0c;用来存放地址&#xff0c;地址唯一标识一块内存空间。 2. 指针的大小是…...

18:CTK 总结篇(FAQ)

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

从Netfilter到IPVS:深入解析Linux内核负载均衡的实现与配置

1. Linux内核网络框架与负载均衡基础 当你打开一个网页或使用手机APP时&#xff0c;后台可能有成百上千台服务器在协同工作。这些服务器如何高效分配流量&#xff1f;这就是负载均衡技术的用武之地。在Linux生态中&#xff0c;从Netfilter到IPVS的技术演进&#xff0c;为我们提…...

2003 - MySQL连接localhost失败(10061错误)的全面排查指南

1. 为什么会出现MySQL连接localhost失败&#xff08;10061错误&#xff09;&#xff1f; 当你兴致勃勃地打开数据库客户端准备大干一场时&#xff0c;突然蹦出个"2003 - Cant connect to MySQL server on localhost(10061)"的错误提示&#xff0c;是不是瞬间就懵了&a…...

OPCUA测试服务器权限问题排查与修复指南

1. 遇到BadUserAccessDenied错误怎么办&#xff1f; 最近在搭建OPCUA测试服务器时&#xff0c;不少小伙伴都遇到了BadUserAccessDenied这个烦人的错误。这个错误代码0x801f0000就像一扇紧闭的大门&#xff0c;明明服务器就在眼前&#xff0c;却因为权限问题无法访问关键数据。作…...

如何快速配置安卓虚拟摄像头VCAM:专业使用技巧完整指南

如何快速配置安卓虚拟摄像头VCAM&#xff1a;专业使用技巧完整指南 【免费下载链接】com.example.vcam 虚拟摄像头 virtual camera 项目地址: https://gitcode.com/gh_mirrors/co/com.example.vcam 安卓虚拟摄像头VCAM是一款基于Xposed框架的创新工具&#xff0c;能够将…...

从 99.8% 到 14.9%:Paperxie AI 降重,让论文 AIGC 焦虑彻底成为过去式

paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AIPPThttps://www.paperxie.cn/weight?type1https://www.paperxie.cn/weight?type1 一、写在前面&#xff1a;被 AIGC 检测支配的论文焦虑&#xff0c;终于有解了 当知网、维普等平台全面升级 AIGC 检测…...

如何用RecastNavigation构建高效AI导航系统:5个实战技巧揭秘

如何用RecastNavigation构建高效AI导航系统&#xff1a;5个实战技巧揭秘 【免费下载链接】recastnavigation Navigation-mesh Toolset for Games 项目地址: https://gitcode.com/gh_mirrors/re/recastnavigation 你是否曾为游戏中的AI角色设计路径规划而头疼&#xff1f…...

Umi-OCR无界面服务化启动指南:将OCR能力无缝集成到自动化工作流

Umi-OCR无界面服务化启动指南&#xff1a;将OCR能力无缝集成到自动化工作流 【免费下载链接】Umi-OCR Umi-OCR: 这是一个免费、开源、可批量处理的离线OCR软件&#xff0c;适用于Windows系统&#xff0c;支持截图OCR、批量OCR、二维码识别等功能。 项目地址: https://gitcode…...

树莓派+SocketCAN实战:手把手教你用CanFestival控制伺服电机(附完整配置文件)

树莓派SocketCAN实战&#xff1a;手把手教你用CanFestival控制伺服电机&#xff08;附完整配置文件&#xff09; 在工业自动化和机器人控制领域&#xff0c;CANopen协议因其高可靠性和实时性成为伺服电机控制的首选方案。本文将带你用树莓派这一低成本硬件平台&#xff0c;结合…...

从零开始学SCL:手把手教你实现天塔之光、数码管显示等工业控制案例(含避坑指南)

从零开始学SCL&#xff1a;手把手教你实现天塔之光、数码管显示等工业控制案例&#xff08;含避坑指南&#xff09; 工业自动化领域中&#xff0c;PLC编程是核心技能之一。而SCL&#xff08;Structured Control Language&#xff09;作为IEC 61131-3标准中的高级文本语言&#…...

如何快速上手Notepad--:3步完成跨平台文本编辑器的配置与使用

如何快速上手Notepad--&#xff1a;3步完成跨平台文本编辑器的配置与使用 【免费下载链接】notepad-- 一个支持windows/linux/mac的文本编辑器&#xff0c;目标是做中国人自己的编辑器&#xff0c;来自中国。 项目地址: https://gitcode.com/GitHub_Trending/no/notepad-- …...