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

C++函数继承

C++函数继承

引言

C++三大特征分别为封装,继承和多态,它们构成了面向对象编程的基石,它们协同工作以提升代码的模块化,可复用性和灵活性

  • 封装:提高代码的维护性(当程序出现问题时可以准确定位)

  • 继承:提高代码的复用性(在不做任何修改或者操作源码就能实现代码的复用)

  • 多态:提高代码的扩展性(后期文章会介绍)

组合

C++中实现代码复用操作主要有两种,分别是组合和继承,二者各有优缺点

#include <iostream>using namespace std;​class A{public:void func(){cout << "Hello world" << endl;}int m_num;};​class B{public:​//创建A类成员A a;​void func(){//此时B包含Aa.func();}};​int main(){B b;b.func();​return 0;}

执行结果:

上述代码就是一个典型的组合操作的实现,B包含A对象作为成员变量,这样B就可以调用A中的方法,此时修改A的内部逻辑并不会影响B(只要接口不变),操作时也更加直接,可以组合多个类,操作方法都是通过成员对象来访问,这样就在不复制代码内容的情况下使用了其他类中的功能。但这种方法每次组合一个类就要多创建一个成员,此时会增大内存占用。

继承

继承同样在代码复用方面起着重要作用

#include <iostream>using namespace std;​class A{public:void print(){cout << "Hello world" << endl;}int m_num;};​class B : public A{public:​//继承之后无需声明A类成员便可直接调用A类内的共有函数void func(){print();}};​int main(){A a;B b;b.func();​//继承了A类之后便可以直接使用与A相同的成员b.m_num = 10;b.print();​cout << b.m_num << endl;cout << a.m_num << endl;​cout << sizeof(b) << endl;​return 0;}​

输出结果

在这里与组合相比,继承就可以减少内存开销,继承之后B称为A的子类或派生类,A称为B的父类。派生类的实例化对象大小:父类的对象大小 + 派生类的新成员;与此同时我们还应该注意继承的空间分配问题,继承后派生类和父类并不公用内存,派生类会在继承后在自己的内存空间内开辟新的内存来存放与父类不同的成员,大致原理如下

根据程序输出结果也不难看出修改了B类成员后A类成员并没有一同发生改变

覆盖

#include <iostream>using namespace std;​class A{public:void print(){cout << "Hello world" << endl;}int m_num = 12;};​class B : public A{public://与父类重名的成员会在派生类中重新创建int m_num;int count;// 继承之后无需声明A类成员便可直接调用A类内的共有函数void func(){print();}​//与父类重名的函数会发生覆盖void print(){cout << "Hi world" << endl;}};​int main(){A a;B b;b.func();​b.m_num = 10;b.print();​cout << sizeof(b) << endl;​cout << b.m_num << endl;cout << a.m_num << endl;​return 0;}

输出结果

根据输出结果不难推理出派生类中的重名函数以及重名成员会覆盖子类中的对应函数和成员

三种继承方式

公有继承

基类的公有成员和属性成为派生类的共有;基类的被保护的属性和方法成为派生类的被保护;基类私有成员不能被继承

保护继承

基类的公有成员和属性成为派生类的私有;基类的被保护的属性和方法成为派生类的私有;基类私有成员不能被继承

私有继承

基类的公有成员和属性成为派生类的被保护的;基类的被保护的属性和方法成为派生类的被保护的;基类私有成员不能被继承

三种继承方式操作方法基本相同,只是权限控制不同,由于我们使用继承的出发点是实现代码复用,所以三种继承方式中使用最多的就是公有继承

组合和继承的选择

当两者之间是has-a(例如:学生有书包,汽车有发动机)关系时通常使用组合方式,当两者关系为is-a关系(例如:老师是人,学生也是人)时使用继承方式

http://www.dtcms.com/a/356860.html

相关文章:

  • 【C++闯关笔记】STL:vector的学习与使用
  • 论文阅读:ICLR 2024 GAIA: A Benchmark for General AI Assistants
  • DBeaver中禁用PostgreSQL SSL的配置指南
  • SQL Server 查看备份计划
  • Creed —— 设置玩家属性(生命/耐力/经验值等)
  • 初学python的我开始Leetcode题-17
  • Azure Marketplace 和 Microsoft AppSource的区别
  • 订餐后台管理系统 -day03 登录模块
  • Linux操作系统Shell脚本-第一章
  • 数据防泄与最小可见:ABP 统一封装行级安全(RLS)+ 列级脱敏
  • 前端vue3入门学习
  • 数据分析编程第七步:分析与预测
  • 【MFC自动生成的文件详解:YoloClassMFC.cpp 的逐行解释、作用及是否能删除】
  • 科技赋能医疗:陪诊小程序系统开发,让就医不再孤单
  • cursor的setting設置換行
  • 舰用燃气机数字孪生:舰船动力智慧管控核心
  • 从0到1玩转 Google SEO
  • 循环高级(1)
  • Parasoft赋能测试:精准捕捉运行时缺陷
  • 深度学习入门Day10:深度强化学习原理与实战全解析
  • 彻底弄清URI、URL、URN的关系
  • 基于LangChain框架搭建AI问答系统(附源码)
  • 将2D基础模型(如SAM/SAM2)生成的2D语义掩码通过几何一致性约束映射到3D高斯点云
  • android 不同分辨图片放错对应文件夹会怎样?
  • Python 编码与加密全解析:从字符编码到 RSA 签名验证
  • (笔记)Android ANR检测机制深度分析
  • 【微知】如何撤销一个git的commit?以及撤销的3种方式?
  • 多代理系统架构:Supervisor 与 Swarm 架构详解
  • Java面试-MySQL事务
  • Word文档怎么打印?Word打印技巧?【图文详解】单面/双面/指定页面/逆序等Word打印选项