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

一文带你深入了解赋值兼容原则

一文带你深入了解赋值兼容原则


文章目录

  • 一文带你深入了解赋值兼容原则
      • 笔记内容解读
      • 什么是赋值兼容规则?
      • 详细讲解与代码示例
      • 为什么是安全的?为什么反过来不安全?
      • 对象切片
      • 与多态的关系
  • 总结

你提供的这张图片笔记非常精准地总结了C++ public继承中的一个核心概念:赋值兼容规则。这个规则是理解C++多态性的基础。我来为你详细解读和扩展一下。

笔记内容解读

你的笔记准确地指出了 public 继承下的三个关键点:

  1. “is-a” 关系:这是 public 继承的语义核心。它表示派生类(子类)是一种特殊种类的基类(父类)。例如,Student(子类)是一种Person(基类)。
  2. 子类对象可以直接赋值给基类对象:这是对象切片的过程。
  3. 子类对象的指针和引用可以指向基类:这是实现多态的基础。

什么是赋值兼容规则?

赋值兼容规则是指在public 继承的前提下,以下三种情况是被允许的(编译器会隐式转换):

  • 情况1:将派生类对象赋值给基类对象
  • 情况2:用基类指针指向派生类对象
  • 情况3:用基类引用指向派生类对象

详细讲解与代码示例

#include<iostream>usingnamespacestd;classBase{public:intbaseValue=10;voidshow(){cout<<"Base::show(), baseValue = "<<baseValue<<endl;}};classDerived:publicBase{public:intderivedValue=20;voidshow(){cout<<"Derived::show(), baseValue = "<<baseValue<<", derivedValue = "<<derivedValue<<endl;}};intmain(){Derived derivedObj;Base baseObj;// --- 1. 子类对象赋值给基类对象 ---baseObj=derivedObj;// ✅ 允许:发生了对象切片baseObj.show();// 输出: Base::show(), baseValue = 10// 注意:derivedObj 中特有的 derivedValue 被“切”掉了,丢失了。// baseObj.derivedValue; // ❌ 错误:baseObj 没有 derivedValue 成员// --- 2. 基类指针指向子类对象 ---Base*basePtr=&derivedObj;// ✅ 允许basePtr->show();// 输出: Base::show(), baseValue = 10// 注意:指针类型是 Base*,所以它认为指向的是 Base 对象,调用了 Base 的 show()// 这就是为什么需要虚函数来实现多态。// --- 3. 基类引用指向子类对象 ---Base&baseRef=derivedObj;// ✅ 允许baseRef.show();// 输出: Base::show(), baseValue = 10// 和指针一样,引用的类型决定了默认调用哪个函数。// --- 反向操作:不安全,不允许隐式转换 ---// Derived* derivedPtr = &baseObj; // ❌ 错误:不能将基类对象地址直接赋给派生类指针// Derived& derivedRef = baseObj; // ❌ 错误:原因同上return0;}

为什么是安全的?为什么反过来不安全?

  • 子类转基类(安全):因为子类对象包含了基类的所有成员。所以,无论是赋值、指针还是引用,你都可以放心地将它当作一个基类对象来使用。你访问的成员,子类里肯定有。这个过程是类型的收缩
  • 基类转子类(不安全):因为基类对象不包含派生类特有的成员。如果允许一个基类指针直接指向一个基类对象,然后程序员试图通过这个指针(可能经过强制转换)去访问派生类特有的成员,就会访问到不存在的内存,导致程序崩溃。这个过程是类型的扩大

对象切片

当你把派生类对象赋值给基类对象时(baseObj = derivedObj),会发生对象切片derivedObj中属于Derived的那部分特有成员(如derivedValue)会被“切掉”,只保留属于Base的部分(如baseValue)来赋值给baseObj。这是一种值拷贝行为。

与多态的关系

赋值兼容规则本身并不等同于多态,但它是实现多态的语法基础

  • 赋值兼容规则允许你用一个基类的指针或引用指向一个派生类对象。
  • 虚函数允许在运行时,根据指针或引用实际指向的对象类型(派生类还是基类),来决定调用哪个版本的函数。

只有当赋值兼容规则 + 虚函数两者结合起来,才构成了 C++ 的运行时多态。

// 实现多态的修正示例classBase{public:virtualvoidshow(){cout<<"Base::show()"<<endl;}// 添加 virtual};classDerived:publicBase{public:virtualvoidshow()override{cout<<"Derived::show()"<<endl;}// 重写};intmain(){Derived derivedObj;Base*basePtr=&derivedObj;// 赋值兼容规则basePtr->show();// 多态:输出 "Derived::show()"return0;}

总结

这篇文章是作者搜集大量面经和资料这里出来的。感谢你的支持
作者wkm是一名中国矿业大学(北京) 大一的新生,希望得到你的关注
如果可以的话,记得一键三联!

http://www.jsqmd.com/news/442502/

相关文章:

  • 2026年成都钢边箱厂家推荐:三大实力品牌深度解析 - 朴素的承诺
  • python+flask的医院康复预约系统 vue
  • 具身智能新纪元:VLA模型如何让机器“看懂世界,听懂人话,动手做事”?
  • 门匠火锅电话查询:如何联系与官方信息核实指南 - 品牌推荐
  • 先琦通讯电话查询:企业采购与数码产品服务指南 - 品牌推荐
  • 软著申请宝典:从代码到资产,守护企业创新价值
  • 2026产品模具定制不踩坑!电子烟模具、镜头模具、精密塑胶模具有哪些?深圳鸿泰合兴塑胶模具厂家精度高、交期准、品质稳 - 栗子测评
  • 手把手教你设计16位乘法器|零门槛入门,跟随课程免费指导
  • 2026就业寒冬下,高职大数据专业凭什么逆势上扬?秘密在这里
  • 2026工业传动带采购不踩坑!假齿同步带、开口同步带、钢丝同步带、输送带、片基带厂家哪家好?麦优迪传动带耐磨抗拉更稳定 - 栗子测评
  • 数据安全无忧:内外网文件交换系统产品推荐与实践案例 - 飞驰云联
  • 大厂、品牌方都在抢的电商人才,到底需要什么能力?
  • Vue3开发项目启动白屏 ERR_CACHE_READ_FAILURE 200 (OK)
  • 2026年快速上手:在阿里云服务器上部署OpenClaw(Clawdbot)的详细教程
  • 先琦通讯电话查询:获取产品信息与定制服务建议 - 品牌推荐
  • 从零开始开发 CNBlog MCP 工具(更新版)
  • 吐血推荐!自考论文神器 —— 千笔·专业论文写作工具
  • 嘉年华旅行社电话查询:官方联系途径与通用建议 - 品牌推荐
  • python+flask的法院庭审辅助系统的研究与发现-vue
  • 探寻优质TWSNS电磁阀生产厂家,广州邢海机电有限公司给出卓越方案,ROSS流量阀,TWSNS电磁阀直销厂家哪家好 - 品牌推荐师
  • 温暖人心的大学创新创业成果突出吗 - 工业设备
  • 采购传动带别盲目!2026PU聚氨酯圆带、平皮带、工业、梯形齿、橡胶、聚氨酯同步带厂家哪家好?麦优迪同步带运行平稳不打滑 - 栗子测评
  • python+flask的流浪猫动物救助系统;领养 s85y8-vue
  • 揭秘2026年成都酒店酒窖酒柜定制排名,看哪家收费合理靠谱 - mypinpai
  • AcWing 892:台阶 ← Nim博弈
  • IP地址数据 赋能社交行业精细化运营与智能匹配
  • python+flask的读书分享评论vue书评
  • 讲讲温度记录仪选购要点,价格和性价比怎么平衡? - 工业品牌热点
  • Clawdbot与ESMAP数字孪生技能融合分析
  • python+flask的车辆违章管理系统-vue