当前位置: 首页 > 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.jsqmd.com/news/931459/

相关文章:

  • ExtractorSharp:一站式游戏资源编辑解决方案,让NPK和IMG文件处理变得简单高效
  • 北京配眼镜推荐,配眼镜都去哪,五家店从验光到售后横向对比 - 配眼镜新资讯
  • Android 性能优化【篇五:应用启动分析流程】
  • vue父子组件通信(二)祖先调用provide / inject(1)vue2
  • 2026四川文旅局备案导游TOP5推荐|正规持证金牌向导官方可查安心出行,专业趣味讲解 - 随峰国旅
  • 福州鼓楼东街口|专业回收钻戒,实体门店放心交易 - 奢侈品回收测评
  • 别再只盯着20/60了!用Backtrader回测SMA双均线,手把手教你找到最适合你的周期参数
  • 3分钟定位热键冲突:Hotkey Detective精准排查方案
  • 2026中国超声波泥位计源头厂家权威推荐榜:从技术实力到工程选型的全景解析 - 仪表品牌排行榜
  • 高性能本地AI字幕生成系统:架构设计与实现原理
  • 网盘直链下载助手:告别限速,实现满带宽下载的终极解决方案
  • 如何用ZonyLrcToolsX三分钟解决音乐库歌词缺失难题?
  • AI-HF_Patch终极指南:5步解锁AI少女完整游戏体验
  • MySQL 8.0教学资源包:26讲PPT课件+配套可运行PHP/SQL代码,含安装配置、查询优化、存储过程、权限控制、主从复制与三个实战项目
  • 避开这些坑!STM32G473 Bootloader开发中CAN/USART升级的5个常见问题与调试心得
  • ibaPDA 7.0.1安装包:支持S7-1200/1500实时曲线监控、故障触发捕获与离线数据分析
  • 药食同源变“智商税”?AI辨体如何用技术撕开政策死结
  • 2026北京配眼镜推荐,到底要花多少,五家店配镜账单全公开 - 配眼镜新资讯
  • 麒麟V10系统4K屏字体太小?三步搞定Mate桌面DPI缩放(实测有效)
  • 2026 温州装修公司避坑指南|选对家装,省心装出理想家 - 速递信息
  • C++11并发编程:call_once一次性执行+atomic原子类型+CAS无锁编程+自旋锁
  • Meshroom:从照片到3D模型的魔法转换,免费开源工具让创作更简单
  • 你的GPU散热真的够吗?深度学习炼丹党必看的温控监控与预警设置指南(以Ubuntu/NVIDIA为例)
  • 3D质感革命:5分钟掌握NormalMap-Online免费在线法线贴图生成器终极指南
  • 2026年只会C语言就业很差吗 C语言真的要完了吗?
  • 3种高效方法:利用OCAuxiliaryTools彻底解决黑苹果配置难题
  • B站m4s视频转换终极指南:一键将缓存视频转为MP4格式
  • 51单片机四则运算计算器完整Keil工程:矩阵键盘输入+数码管显示(含源码与HEX)
  • 越南MobiFone MFY99套餐取消全攻略:短信与App双通道详解
  • 保姆级教程:用LeRobot复现斯坦福ALOHA的ACT算法,搞定双臂分拣任务