【C++】十、继承

news2024/11/22 19:48:55

一、继承的概念及定义

继承(inheritance)机制是面向对象程序设计使代码可以 复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。
class Person
{
public:
   void Print()
   {
       cout << "name:" << _name << endl;
       cout << "age:" << _age << endl;
   }
protected:
   string _name = "peter"; // 姓名
   int _age = 18;  // 年龄
};
// 继承后父类的Person的成员(成员函数+成员变量)都会变成子类的一部分。这里体现出了
//Student和Teacher复用了Person的成员。下面我们使用监视窗口查看Student和Teacher对象,可
//以看到变量的复用。调用Print可以看到成员函数的复用。
class Student : public Person
{
protected:
   int _stuid; // 学号
};
class Teacher : public Person
{
protected:
   int _jobid; // 工号
};
int main()
{
   Student s;
   Teacher t;
   s.Print();
   t.Print();
   return 0;
}
定义
基类(父类);派生类(子类);
继承基类成员访问方式的变化
总结
1. 基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。
2. 基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。
3. 实际上面的表格我们进行一下总结会发现,基类的私有成员在子类都是不可见。基类的其他成员在子类的访问方式 == Min(成员在基类的访问限定符,继承方式),public > protected > private。
4. 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。
5. 在实际运用中一般使用都是public继承,几乎很少使用protetced/private继承,也不提倡使用protetced/private继承,因为protetced/private继承下来的成员都只能在派生类的类里面使用,实际中扩展维护性不强

二、基类和派生类对象赋值转换

派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用。这里有个形象的说法叫切片或者切割。寓意把派生类中父类那部分切来赋值过去。
基类对象不能赋值给派生类对象。
基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。但是必须是基类的指针是指向派生类对象时才是安全的。这里基类如果是多态类型,可以使用RTTI(RunTime Type Information)的dynamic_cast 来进行识别后进行安全转换。
class Person
{
protected :
    string _name; // 姓名
    string _sex;  // 性别
    int _age; // 年龄
};
class Student : public Person
{
public :
    int _No ; // 学号
};

void Test ()
{
     Student sobj ;
     // 1.子类对象可以赋值给父类对象/指针/引用 切割/切片
     Person pobj = sobj ;
     Person* pp = &sobj;
     Person& rp = sobj;
    
     //2.基类对象不能赋值给派生类对象
     sobj = pobj;
    
    // 3.基类的指针可以通过强制类型转换赋值给派生类的指针
     pp = &sobj
     Student* ps1 = (Student*)pp; // 这种情况转换时可以的。
     ps1->_No = 10;
    
     pp = &pobj;
     Student* ps2 = (Student*)pp; // 这种情况转换时虽然可以,但是会存在越界访问的问题
    ps2->_No = 10;
}

三、继承中的作用域

1. 在继承体系中基类和派生类都有独立的作用域。
2. 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问)
3. 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。
4. 注意在实际中在继承体系里面最好不要定义同名的成员。

四、派生类的默认成员函数

6个默认成员函数,“默认”的意思就是指我们不写,编译器会变我们自动生成一个,那么在派生类中,这几个成员函数是如何生成的呢?
1. 派生类的构造函数必须调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用。
2. 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。
3. 派生类的operator=必须要调用基类的operator=完成基类的复制。
4. 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。
5. 派生类对象初始化先调用基类构造再调派生类构造。
6. 派生类对象析构清理先调用派生类析构再调基类的析构。
7. 因为后续一些场景析构函数需要构成重写,重写的条件之一是函数名相同(这个我们后面会讲解)。那么编译器会对析构函数名进行特殊处理,处理成destrutor(),所以父类析构函数不加virtual的情况下,子类析构函数和父类析构函数构成隐藏关系。
注:
以下情况下子类需要自己写
1、父类没有默认构造,需要我们自己显示写构造;
2、如果子类有资源需要释放,就需要自己显示写析构;
3、如果子类存在浅拷贝问题,就需要自己显示拷贝构造和赋值解决浅拷贝问题;

写的方法:
1、父类的调用父类函数;
2、自己的调用当普通处理;

五、继承与友元

友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员;

六、 继承与静态成员

基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子
类,都只有一个static成员实例;

七、复杂的菱形继承及菱形虚拟继承

单继承:一个子类只有一个直接父类时称这个继承关系为单继承
多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承
菱形继承:菱形继承是多继承的一种特殊情况。
菱形继承的问题:数据冗余,二义性;
虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系,在Student和
Teacher的继承Person时使用虚拟继承,即可解决问题。需要注意的是,虚拟继承不要在其他地
方去使用;
虚拟继承解决数据冗余和二义性的原理
class A
public:
 int _a;
};
// class B : public A
class B : virtual public A
{
public:
 int _b;
};
// class C : public A
class C : virtual public A
{
public:
 int _c;
};
class D : public B, public C
{
public:
 int _d;
};
int main()
{
 D d;
 d.B::_a = 1;
 d.C::_a = 2;
 d._b = 3;
 d._c = 4;
 d._d = 5;
 return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/337538.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flink CEP 新特性进展与在实时风控场景的落地

摘要&#xff1a;本文整理自阿里云开发工程师耿飙&阿里云开发工程师胡俊涛&#xff0c;在 FFA 实时风控专场的分享。本篇内容主要分为四个部分&#xff1a;Flink CEP 介绍&新功能解读动态多规则支持与 DemoFlink CEP SQL 语法增强未来规划■ 分享中的动态 CEP 和 CEP S…

mysql面试题(集合)

mysql如何实现索引机制 mysql中索引分三类&#xff1a;B树索引、Hash索引、全文索引 InnoDB索引与MYISAM索引实现的区别是什么 1.InnoDB的辅助索引data域存储相应记录主键的值而不是地址 2.InnoDB的数据文件本身就是主索引文件 3.MyISAM的索引和数据是分开存储的 一个表中如…

ChatGPT 来了,你准备好了吗?

周三的晚上&#xff0c;我做了一次直播&#xff0c;题目叫做《ChatGPT 来了&#xff0c;老师和同学们准备好了吗&#xff1f;》。如果你还没看&#xff0c;欢迎看看回放视频。做这次直播&#xff0c;是因为受了三重刺激。第一重&#xff0c;来自于我的一位好友&#xff0c;也是…

自上而下的传输协议-TCP/IP 的演化

动机来自昨天下班路上快到家发的一则朋友圈&#xff1a; 作为因果的历史是不存在的。因为有无数种对等的解释。这个可以用拓扑学证明的&#xff0c;模型非常简单&#xff0c;事件作为点&#xff0c;事件之间的关系作为连接两点的有向边。 最近思考一个问题&#xff0c;传输协…

MongoDB 更新文档

MongoDB 使用 update() 和 save() 方法来更新集合中的文档。 update() 方法 update() 方法用于更新已存在的文档。语法格式如下&#xff1a; db.collection.update(<query>,<update>,{upsert: <boolean>,multi: <boolean>,writeConcern: <document…

移除元素-力扣27-java

一、题目描述给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新…

数据与C(整数存储的各种类型)

目录 一.int&#xff08;%d&#xff09; 1.sizeof应用 2.声明int变量以及初始化 3.打印int值 二.short&#xff08;%hd&#xff09;和long(%ld) 1.short大小 2.long大小 3.short和long的分支 三.综合讲解 四.整数类型总结 五.可移植类型&#xff1a; stdint.h 和 in…

年轻人越来越反感“专家”,问题出在哪儿?

专家的建议&#xff0c;又惹怒了年轻人。 最近&#xff0c;某学者表示&#xff0c;在鼓励年轻人生育、婚恋的问题上&#xff0c;可以将法定结婚年龄下调至18岁&#xff0c;以此降低成婚门槛促进单身男女建立家庭。 此话一出&#xff0c;立刻引来无数板砖。不少人质疑&#xf…

CrossOver2023mac跨系统互通切换win虚拟机

CrossOver2023版是在Mac上运行Win软件的最简单方法&#xff0c;有了它&#xff0c;你无须 Win许可、重新启动或使用虚拟机即可在mac上使用Win软件。CrossOver23可以轻松地从Dock本地启动Win程序。CrossOver版还集成了macOS 功能&#xff0c;例如跨平台复制和粘贴&#xff0c;以…

数据与C(ASCII码,char)

目录 一.ASCII码讲解 二.非打印字符&#xff08;转义字符&#xff09; 三.扩展小知识 一.ASCII码讲解 char类型用于存储字符&#xff0c;从技术层面看&#xff0c;char时整数类型&#xff0c;因为char类型实际上存储的是整数而不是字符。计算机使用数字编码来处理字符&…

javaEE 初阶 — 超时重传机制

文章目录超时重传机制1. 数据重复传输问题2. 如何解决数据重复传输问题3. 重传次数问题TCP 的工作机制&#xff1a;确认应答机制 超时重传机制 如果传输数据的时候丢包了该怎么办&#xff1f; 利用 超时重传&#xff0c;也就是超过了一定的时间&#xff0c;如果还没响应就重新…

回顾 | 开学季(一)- 在 Windows / macOS 上配置你的开发环境

点击蓝字关注我们编辑&#xff1a;Alan Wang排版&#xff1a;Rani Sun微软 Reactor 为帮助广开发者&#xff0c;技术爱好者&#xff0c;更好的学习 .NET Core, C#, Python&#xff0c;数据科学&#xff0c;机器学习&#xff0c;AI&#xff0c;区块链, IoT 等技术&#xff0c;将…

社交登陆OAuth2.0

QQ、微博、github 等网站的用户量非常大&#xff0c;别的网站为了 简化自我网站的登陆与注册逻辑&#xff0c;引入社交登陆功能&#xff1b; 步骤&#xff1a; 1&#xff09;、用户点击 QQ 按钮 2&#xff09;、引导跳转到 QQ 授权页 3&#xff09;、用户主动点击授权&#xff…

Linux 服务器(centos7)搭建 Web 版 VSCode

首先到code-server的git地址找到下载链接 打开https://github.com/cdr/code-server/releases&#xff0c;选择一个版本下载&#xff0c;我选择的是code-server-4.9.1-linux-amd64.tar.gz&#xff0c;这是 64 位 Linux 的通用版。 下载压缩包到服务器并解压 cd /home mkdir v…

Python-第四天 Python循环语句

Python-第四天 Python循环语句一、while循环1.while循环的基础语法2.while循环的基础案例3.while循环的嵌套应用4.while循环的嵌套案例二、for循环1.for循环的基础语法1.1基础语法1.2 range语句2.for循环的嵌套应用三、循环中断 : break和continue1.continue2.break四、 综合案…

nginx相关反爬策略总结笔记

引言 互联网站点的流量一部分由人类正常访问行为产生&#xff0c;而高达30%-60%的流量则是由网络爬虫产生的&#xff0c;其中一部分包含友好网络爬虫&#xff0c;如搜索引擎的爬虫、广告程序、第三方合作伙伴程序、Robots协议友好程序等;而并非所有的网络爬虫都是友好的&#x…

【C#项目】图书馆管理系统-WinForm+MySQL

文章目录前言一、业务梳理与需求分析1.功能描述2.实现步骤3.功能逻辑图二、数据库设计1.实体-关系&#xff08;E-R图&#xff09;概念模型设计2.数据表设计三、WinForm界面交互设计1、界面交互逻辑2、项目树3、主界面登录界面4、 图书查询界面5、图书借阅界面6、图书插入界面7、…

pixhawk2.4.8-地面站配置-APM固件

目录一、硬件准备二、APM固件、MP地面站下载三、地面站配置1 刷固件2 机架选择3 加速度计校准4 指南针校准5 遥控器校准6 飞行模式7 紧急断电&无头模式8 基础参数设置9 电流计校准10 电调校准11 起飞前检查&#xff08;每一项都非常重要&#xff09;12 飞行经验四、遇到的问…

10.数据库恢复技术

其他章节here 梳理 名词解释 事务&#xff1a;事务是用户定义的 一个数据操作序列&#xff0c;这些操作要么全做&#xff0c;要么全不做&#xff0c;是一个不可分割的工作单位 事务≠程序 事务是恢复和并发控制的基本单位 &#xff08;事务时数据库应用程序的基本逻辑单元&am…

制造业升级转型:制造业上市公司-智能制造词频统计数据集

发展智能制造&#xff0c;关乎中国制造业转型升级的成效。基于中国制造业上市公司年报&#xff0c;通过文本数据挖掘&#xff0c;提取关键词反映企业对智能制造的关切焦点&#xff0c;进而运用词频及共词网络分析&#xff0c;洞察中国智能制造的发展态势。 研究发现&#xff0…