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

c++: 继承(下)



继承与静态成员变量


基类定义了static静态成员,则整个继承体系⾥⾯只有⼀个这样的成员。⽆论派⽣出多少个派⽣类,都只有⼀个static成员实例。

classPerson{public:string _name;staticint_count;};intPerson::_count=0;classStudent:publicPerson{protected:int_stuNum;};intmain(){Person p;Student s;// 这⾥的运⾏结果可以看到⾮静态成员 _name 的地址是不⼀样的// 说明派⽣类继承下来了,⽗派⽣类对象各有⼀份cout<<&p._name<<endl;cout<<&s._name<<endl;// 这⾥的运⾏结果可以看到静态成员 _count 的地址是⼀样的// 说明派⽣类和基类共⽤同⼀份静态成员cout<<&p._count<<endl;cout<<&s._count<<endl;// 公有的情况下,⽗派⽣类指定类域都可以访问静态成员cout<<Person::_count<<endl;cout<<Student::_count<<endl;return0;}

可以看到基类中定义的static成员变量在基类自己那和派生类都是同一个地址,而指定类域对象count值和指定派生类类域count值相同,能证明static静态成员变量在基类和派生类都是公用一个地址


多继承

单继承:⼀个派⽣类只有⼀个直接基类时称这个继承关系为单继承
多继承:⼀个派⽣类有两个或以上直接基类时称这个继承关系为多继承,多继承对象在内存中的模型
是,先继承的基类在前⾯,后⾯继承的基类在后⾯,派⽣类成员在放到最后⾯。

classPerson{public:string _name;// 姓名};classStudent:publicPerson{protected:};int_num;//学号classTeacher:publicPerson{protected:int_id;// 职⼯编号};classAssistant:publicStudent,publicTeacher{protected:string _majorCourse;// 主修课程};intmain(){// 编译报错:error C2385: 对“_name”的访问不明确Assistant a;a._name="peter";// 需要显⽰指定访问哪个基类的成员可以解决⼆义性问题,但是数据冗余问题⽆法解决a.Student::_name="xxx";a.Teacher::_name="yyy";return0;}

多继承的语法就如上图的代码,派生类的基类也会有它的基类,上面的意思是,我假设为博士生,我可能是某科院长的学生,我还可以是某主修课程的老师,我这两个身份的我的真实名字是我这两个身份公共的,所以我定义一个Person作为它们的基类
然后你照着写的话然后调试窗口看一下创建的对象,会发现同一个对象有两个Person类,一个是student中的,一个是teacher中的,我不管是什么身份我的名字都是同一个,所以这就导致数据冗余
还有你如果这样写:

Assistant a;a._name="peter";

会报错,编译器会报不知道指定哪一个_name,因为你Assistant中继承的student和teacher中都有继承Person的_name,所以编译器才会报这个错误,这就是二义性
所以在这里可以把name定义为Assistant的私有成员,只是这样违背了实际生活
这种情况是多继承的特殊情况:菱形继承


菱形继承

菱形继承:菱形继承是多继承的⼀种特殊情况。菱形继承的问题,从下⾯的对象成员模型构造,可以
看出菱形继承有数据冗余和⼆义性的问题,在Assistant的对象中Person成员会有两份。⽀持多继承就⼀定会有菱形继承,像Java就直接不⽀持多继承,规避掉了这⾥的问题,所以实践中我们也是不建议设计出菱形继承这样的模型的



所以要解决数据冗余和二义性的话就要引出下面的知识: 虚继承

虚继承

很多⼈说C++语法复杂,其实多继承就是⼀个体现。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂,性能也会有⼀些损失,所以最好不要设计出菱形继承。多继承可以认为是C++的缺陷之⼀,后来的⼀些编程语⾔都没有多继承,如Java。

语法就是在会产生冗余的类加上virtual,比如在上面案例中,Student和Teacher里都有Person的成员,那就在它们继承Person中加vitrual

classPerson{public:Person(constchar*name):_name(name){}string _name;// 姓名};classStudent:virtualpublicPerson{public:Student(constchar*name,intnum):Person(name),_num(num){}protected:int_num;//学号};classTeacher:virtualpublicPerson{public:Teacher(constchar*name,intid):Person(name),_id(id){}protected:int_id;// 职⼯编号};

只看创建类的名称那,就是增加了virtual,里面的构造和单继承是一样的
那Assistant的构造有点不一样我先写出来引出个题来,然后再解答
a对象的名字最终是什么?

classAssistant:publicStudent,publicTeacher{public:Assistant(constchar*name1,constchar*name2,constchar*name3,intnum,intid,constchar*majorCourse):Person(name3),Student(name2,num),Teacher(name1,id),_majorCourse(majorCourse){}protected:string _majorCourse;// 主修课程};intmain(){Assistanta("张三","李四","王五",25565,1005,"计算机工程");

这里的答案是名字最后是王五
原因: 这里编译器做了特殊处理在构造函数中虽然你写了派生类Assistant在各个基类中构造基类它们自己的成员,但是它不会走它们构造的Person()这个初始化列表中的,只会走student和teacher它的基类Person中的构造去构造name,这也是为什么在Assistant中多了额外要写的Person

a._name="peter";a.Student::_name="xxx";a.Teacher::_name="yyy";

而且这里改的话在调试窗口中student和teachet中的name都会改,就证明虚继承中是公用一个继承的基类成员,

所以虚继承的特点:
1.在这里的Assistant中的student和teacher中的Person是指针偏移量或指针(具体看编译器如何处理)
2. 如果是student和teachet的对象,那构造函数会正常走它的基类的整体构造

后面我再写的多态会很好体现

http://www.zskr.cn/news/1442793.html

相关文章:

  • 2026四川文旅局备案导游TOP5推荐|正规持证金牌向导官方可查安心出行,专业趣味讲解 - 随峰国旅
  • ExtractorSharp:一站式游戏资源编辑解决方案,让NPK和IMG文件处理变得简单高效
  • 福州鼓楼东街口|专业回收钻戒,实体门店放心交易 - 奢侈品回收测评
  • 高性能本地AI字幕生成系统:架构设计与实现原理
  • AI-HF_Patch终极指南:5步解锁AI少女完整游戏体验
  • 2026北京配眼镜推荐,到底要花多少,五家店配镜账单全公开 - 配眼镜新资讯
  • 51单片机四则运算计算器完整Keil工程:矩阵键盘输入+数码管显示(含源码与HEX)
  • 3分钟告别百度网盘限速!免费开源下载助手让你速度飙升10倍
  • Windows下可直接运行的SpringBoot视频剪辑工具:支持剪辑、加字幕、音画合成
  • “收你们来了”!2026 6 月 - 主流 AI 编程平台全面收紧订阅
  • 基于STM32F103的T12焊台温控主板方案:含多版原理图、Arduino源码与OLED图形化菜单
  • GHelper华硕笔记本轻量控制神器:高效替代方案实战指南
  • QSPI pSRAM嵌入式存储CSS1604LS高稳定国产PSRAM工作机制与规范
  • 四轮独立驱动电动汽车转弯能耗最小化转矩控制【附仿真】
  • 知网维普查重 Turnitin 双适配!Okbiye 论文降重 + 降 AIGC 功能实测,解决重复率与 AI 痕迹双难题
  • 从R的clusterProfiler到Python的gseapy:手把手教你完成ORA分析并解读结果(附代码避坑)
  • 终极指南:3步掌握AMD Ryzen电源调试神器,让系统稳定性提升50%
  • 告别翻车!TC264智能车摄像头循迹进阶:手把手教你优化八邻域算法,搞定环岛和三岔路
  • 不想折腾环境?Hermes Windows 一键部署方案详解
  • 别再死记硬背Delta方法公式了!用Python模拟带你直观理解统计量的变换与收敛
  • C#双界面PLC通信实战包:WinForm+WPF+Modbus TCP直连示例
  • 鸣潮自动化助手:三分钟解放双手,智能完成日常与声骸收集
  • 基于Arduino与直流伺服电机的低成本桌面CNC绘图机制作全攻略
  • QMC解码器:解锁音乐自由的现代解决方案
  • Unity书页卷曲插件完整指南:如何在5分钟内创建逼真的翻页效果
  • LanzouAPI:5分钟掌握蓝奏云直链解析,让文件下载告别繁琐跳转
  • 带GUI的YOLO图像自动标注工具,兼容v5/v8和自定义模型,含一键运行代码与标注数据
  • MATLAB版NSGA-II多目标优化工具包:含完整源码、逐函数文档与可运行示例
  • 生成式AI如何重塑新闻生产:从自动化写作到人机协同的未来
  • K8s Deployment 扩容 10 个实战案例(项目教学法)【20260601】001篇