C++的核心--继承
目录前言一、继承的概念及定义二、基类和派生类对象赋值转换三、继承中的作用域四、派生类的默认成员函数五、继承与友元六、继承与静态成员七、复杂的菱形继承及菱形虚拟继承一单继承与多继承二菱形继承三菱形虚拟继承八、继承的总结和反思结语前言在C 编程世界里继承是一项极为关键的特性它为代码的复用和层次化设计提供了强大支持。掌握继承机制对于编写高效、可维护的C 代码至关重要。今天就让我们一起深入探究C 中的继承。一、继承的概念及定义继承是面向对象程序设计实现代码复用的重要手段。它允许我们在保持原有类特性的基础上进行扩展产生新的类即派生类。这体现了面向对象程序设计的层次结构从简单到复杂逐步构建。定义格式上以class Student : public Person为例Person 是基类父类 Student 是派生类子类 public 是继承方式。继承方式有 public 、 protected 和 private 三种不同继承方式会改变基类成员在派生类中的访问权限。比如基类的 public 成员在 public 继承下在派生类中仍是 public 成员但在 protected 继承下就变为派生类的 protected 成员 。二、基类和派生类对象赋值转换派生类对象和基类对象之间存在特殊的赋值转换关系。派生类对象可以赋值给基类的对象、指针或引用这就像把派生类中属于基类的那部分“切”出来进行赋值形象地称为切片。例如Student sobj; Person pobj sobj; Person* pp sobj; Person rp sobj;然而基类对象不能直接赋值给派生类对象。不过基类的指针或引用可以通过强制类型转换赋值给派生类的指针或引用但这种转换需要谨慎若基类是多态类型可助 RTTI 运行时类型信息的 dynamic_cast 来确保安全转换。在 C 继承体系中向上转型和向下转型是绕不开的核心概念也是面试高频考点与日常编码的常用操作。很多同学对这两个概念模糊不清分不清使用场景、安全性与语法规则今天就用最通俗、最清晰的方式把转型的所有要点一次性讲透。什么是向上/向下转型首先明确C 没有「向上继承」「向下继承」的语法这两个词是对「继承体系中类型转换方向」的通俗叫法。我们默认基类父类在上派生类子类在下所有转换都围绕父子类指针/引用展开。- 向上转型Upcast子类指针/引用 → 父类指针/引用- 向下转型Downcast父类指针/引用 → 子类指针/引用简单记往上转是子类变父类往下转是父类变子类。向上转型永远安全自动支持向上转型是天然合法、无风险的转换也是编码中最常用的转型方式。1. 适用条件仅需满足一个核心要求公有继承public inheritance。因为公有继承代表「is-a」关系子类是父类的一种子类对象天然包含父类的所有成员所以可以直接当作父类使用。2. 语法示例// 父类 class Parent { }; // 子类公有继承父类 class Child : public Parent { }; int main() { Child child; // 向上转型自动完成无需强制转换 Parent* p child; // 指针向上转型 Parent ref child; // 引用向上转型 return 0; }3. 核心特点✅ 自动转换编译器直接允许无需手动强转✅ 绝对安全不会出现未定义行为✅ 多态基础配合虚函数实现运行时多态是面向对象的核心用法向下转型语法允许风险自负向下转型是逆向转换编译器不会自动允许必须手动强制转换且存在安全风险。1. 安全的向下转型唯一安全场景被转换的父类指针/引用原本就指向子类对象先向上转型再转回子类。2. 语法示例Child child; Parent* p child; // 先向上转型 // 向下转型用static_cast强制转换 Child* c static_castChild*(p);3. 危险的向下转型如果父类指针/引用原本指向的是父类对象强行向下转型会触发未定义行为程序崩溃、内存错误等。Parent parent; // 错误父类对象强行转子类风险极大 Child* c static_castChild*(parent);4. 安全方案dynamic_cast 运行时检查当类存在**多态至少一个虚函数**时使用 dynamic_cast 可在运行时检测转型是否合法失败则返回空指针。 class Parent { public: // 虚函数构成多态 virtual ~Parent() default; }; class Child : public Parent { }; int main() { Parent* p new Child; // 运行时安全检测 if (Child* c dynamic_castChild*(p)) { // 转型成功指针确实指向子类对象 } else { // 转型失败处理错误 } delete p; return 0; }一张表总结核心规则转型类型 转换方向 安全性 语法要求 核心场景向上转型 子类→父类 绝对安全 公有继承自动转换 多态、函数传参、接口统一向下转型 父类→子类 有风险 需手动强转原对象为子类 调用子类独有成员口诀面试/编码必背1. 公有继承下向上转型随便用自动安全无压力2. 向下转型需谨慎原对象是子类才安全3. 多态场景用 dynamic_cast 运行时检测防崩溃。掌握以上规则就能彻底搞定 C 继承中的转型问题既避开编码坑也能轻松应对面试提问。如果Personps;实际上是将子类对象作为父类的别名。赋值指针都是兼容切割切片。三、继承中的作用域在继承体系中基类和派生类都有各自独立的作用域。当子类和父类存在同名成员时子类成员会屏蔽父类对同名成员的直接访问这种现象称为隐藏重定义。比如class Person { protected: int _num 111; }; class Student : public Person { protected: int _num 999; public: void Print() { cout Person::_num: Person::_num endl; cout Student::_num: _num endl; } };在 Student 类的 Print 函数中通过 Person::_num 明确访问父类的 _num 成员避免混淆。实际编程中应尽量避免在继承体系里定义同名成员以免造成代码理解和维护上的困难。四、派生类的默认成员函数当我们定义派生类时即便没有显式编写编译器也会自动生成一些默认成员函数主要包括以下几个方面1. 构造函数派生类的构造函数必须调用基类的构造函数来初始化基类的那部分成员。若基类没有默认构造函数就需在派生类构造函数的初始化列表中显式调用合适的基类构造函数。编译过程中子类有两组成员一组是自身的一组是继承而来编译过程中会先初始化基类再初始化派生类派生类有默认构造才行派生类只初始化自己的成员编译器默认把继承而来的的对象交给父类初始化但是不可以以--子类对象(初始化变量)--显示调用父类的默认构造如果没有默认构造--会报错需要以person(成员名)的形式调用父类交给他的默认构造如下所示2. 拷贝构造函数派生类的拷贝构造函数要调用基类的拷贝构造函数完成基类成员的拷贝初始化。子类拷贝构造时如果基类无拷贝构造默认调入默认构造,如果默认构造也没有会报错3. 赋值运算符函数派生类的 operator 必须调用基类的 operator 来完成基类成员的复制。避免隐藏4. 析构函数派生类的析构函数在被调用完成后会自动调用基类的析构函数以清理基类成员确保对象资源的正确释放遵循先派生类后基类的清理顺序。不需要如下这样显示调用否则会二次析构。同时还有一个原因就是如果析构是先父亲后儿子子类析构中有调用父类成员函数就会有坑。五、继承与友元友元关系在继承体系中是不能自动继承的。也就是说基类的友元不能访问子类的私有和保护成员。父亲的朋友不是你的朋友你需要和他成为朋友才可以访问见注释例如class Student; class Person { public: friend void Display(const Person p, const Student s); protected: string _name; }; class Student : public Person { //public: //friend void Display(const Person p, const Student s); protected: int _stunNum; }; void Display(const Person p, const Student s) { cout p._name endl; cout s._stunNum endl; }这里 Display 函数作为 Person 类的友元能访问 Person 类的保护成员但对于 Student 类它并不具备天然访问其保护成员的权限。六、继承与静态成员若基类定义了 static 静态成员那么在整个继承体系中无论派生出多少个子类都只会存在一个该静态成员的实例。例如class Person { public: Person() { _count; } public: static int _count; }; int Person::_count 0; class Student : public Person { };Person 类中的 _count 静态成员在 Student 类及其他派生类中都是共享的可通过类名或对象来访问。七、复杂的菱形继承及菱形虚拟继承一单继承与多继承单继承是指一个子类只有一个直接父类关系简单明了。而多继承则是一个子类有两个或以上直接父类这种情况虽然增加了代码复用的灵活性但也引入了一些复杂问题。二菱形继承菱形继承是多继承的一种特殊情况。以 class Assistant : public Student, public Teacher 为例 Student 和 Teacher 都继承自 Person 这样 Assistant 中就会出现 Person 成员的两份拷贝导致数据冗余和二义性问题。比如在访问 Assistant 对象中来自 Person 的成员时编译器无法明确确定访问的是哪一个 Person 成员。数据冗余和二义性Assistant 中就会出现 Person 成员的两份拷贝三菱形虚拟继承为解决菱形继承的数据冗余和二义性问题引入了虚拟继承。在 Student 和 Teacher 继承 Person 时使用虚拟继承如class Student : virtual public Person就能确保在 Assistant 对象中只存在一份 Person 成员的拷贝。虚拟继承通过虚基表指针和虚基表来管理基类成员的存储和访问有效解决了上述问题但也增加了一定的实现复杂度。原理图示例代码下图是菱形虚拟继承的内存对象成员模型这里可以分析出D对象中将A放到的了对象组成的最下面这个A同时属于B和C那么B和C如何去找到公共的A呢这里是通过了B和C的两个指针指向的一张表。这两个指针叫虚基表指针这两个表叫虚基表。虚基表中存的偏移量。通过偏移量可以找到下面的A。八、继承的总结和反思继承在C 中是把双刃剑。它极大地促进了代码复用构建了清晰的类层次结构但也带来了一些问题。多继承衍生出的菱形继承和复杂的底层实现让代码复杂度和维护难度上升这也是许多其他面向对象语言如Java不采用多继承的原因。在实际编程中我们要谨慎选择继承和组合。继承是“is - a”关系每个派生类对象都是一个基类对象组合是“has - a”关系一个类包含另一个类的对象。优先考虑对象组合因为它耦合度低代码维护性好更符合“黑箱复用”原则而继承适用于需要体现类之间层次关系或实现多态的场景。结语C 的继承机制丰富而复杂深入理解它的各个方面从基本概念到复杂应用能让我们在编程时更得心应手编写出结构良好、高效且易于维护的代码。希望通过这篇博客大家能对C 继承有更透彻的认识在后续编程实践中灵活运用。

相关新闻

小白程序员必看:轻松掌握大模型技能,收藏这份从入门到精通的指南

小白程序员必看:轻松掌握大模型技能,收藏这份从入门到精通的指南

本文全面解析了Claude的“技能”功能,对比了MCP、Commands、SubAgents等同类功能,阐述了技能如何通过预设提示词和工具使用,让AI完成复杂任务。文章深入浅出地介绍了技能的创建方式、运行原理,并分析了其在渐进式披露和节省Token消…

2026/7/5 2:36:43 阅读更多 →
Byte Buddy 进阶指南:攻克 Android 运行时与泛型迷局

Byte Buddy 进阶指南:攻克 Android 运行时与泛型迷局

在之前的文章中,我们领略了 Byte Buddy 在标准 JVM 环境下通过 Java Agent 实现“上帝视角”字节码增强的强大能力。然而,现实世界的开发场景往往更加复杂:你可能需要在 Android 设备上动态生成代码,或者需要生成能被 Jackson、Hi…

2026/7/5 7:55:51 阅读更多 →
照着用就行:专科生专属降AIGC工具,千笔·降AIGC助手 VS 学术猹

照着用就行:专科生专属降AIGC工具,千笔·降AIGC助手 VS 学术猹

在AI技术快速发展的今天,越来越多的专科生开始借助AI工具辅助论文写作,以提高效率、优化内容。然而,随着学术查重系统对AI生成内容的识别能力不断提升,如何有效降低AIGC率和重复率,成为许多学生面临的核心难题。面对市…

2026/7/5 22:48:19 阅读更多 →

最新新闻

避开 Playwright 常见陷阱,让你的 UI 测试更快更稳

避开 Playwright 常见陷阱,让你的 UI 测试更快更稳

做UI自动化测试的朋友应该都有过这种体验——本地跑得好好的,一上CI就挂;周一全绿,周二莫名其妙红一片;加了sleep能过,不加就报元素找不到。 如果你也遇到过这些情况,别急着怀疑是自己的代码写得不够好。很…

2026/7/6 2:57:57 阅读更多 →
AI Agent Skills:从代码补全到智能开发的效率革命

AI Agent Skills:从代码补全到智能开发的效率革命

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 如果你还在用 AI 编程助手只是让它帮你补全代码行,那你可能只发挥了它 10% 的潜力。真正的效率革命,发生在你教…

2026/7/6 2:57:57 阅读更多 →
SONiC 2024 容器化架构解析:10个核心Docker容器如何驱动网络转发

SONiC 2024 容器化架构解析:10个核心Docker容器如何驱动网络转发

SONiC 2024容器化架构深度解析:10个核心容器如何构建下一代云网络1. 现代网络操作系统的容器化革命当微软在2016年首次开源SONiC项目时,很少有人能预料到这个基于Linux的网络操作系统会彻底改变数据中心网络的构建方式。八年后的今天,SONiC已…

2026/7/6 2:55:56 阅读更多 →
QooBot:全栈开源的仿生人操作系统——软硬一体,自由制造

QooBot:全栈开源的仿生人操作系统——软硬一体,自由制造

QooBot:全栈开源的仿生人操作系统——软硬一体,自由制造 摘要:QooBot 是一个面向仿生人的开源全栈生态,涵盖从机械图纸、电路设计到操作系统、AI 算法的完整技术栈。本文从架构全景、大脑核心、推理引擎、开发者生态等维度全面解读…

2026/7/6 2:53:55 阅读更多 →
可变级数LC无源自均压海量级联多电平拓扑机理研究——代替传统LCC/MMC的新一代特高压直流逆变架构

可变级数LC无源自均压海量级联多电平拓扑机理研究——代替传统LCC/MMC的新一代特高压直流逆变架构

可变级数LC无源自均压海量级联多电平拓扑机理研究——取代传统LCC/MMC的新一代特高压直流逆变架构 ----------作者:杨连江 摘要 针对我国特高压直流输电现有两大技术体系(LCC电网换相直流、MMC柔性直流)存在的底层机理缺陷,本文提…

2026/7/6 2:53:55 阅读更多 →
卡梅德生物技术快报| KM13 辅助噬菌体的天然 VHH 噬菌体文库全套构建流程与数据验证

卡梅德生物技术快报| KM13 辅助噬菌体的天然 VHH 噬菌体文库全套构建流程与数据验证

一、提出问题:实验室自建纳米抗体文库常遇四大工程化痛点 食品检测实验室自主构建 VHH 噬菌体文库时,普遍存在工程化落地难题:其一,普通单轮 PCR 扩增 VHH 基因存在大量缺失,文库多样性不足;其二&#xff…

2026/7/6 2:51:55 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻