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

C++ 继承完全指南

1. 概述继承Inheritance是面向对象编程的三大特性之一封装、继承、多态。在 C 中继承允许我们创建一个新类派生类 derived class基于另一个已有的类基类 base class从而重用、扩展或修改基类的行为。继承的主要作用代码复用派生类自动拥有基类的成员数据和方法。建立层次结构表达“is-a”关系如Derived是Base的一种。支持多态通过虚函数实现运行时多态。2. 继承的基本语法cppclass Base { // ... }; class Derived : access-specifier Base { // ... };其中access-specifier可以是public、protected或private决定了基类成员在派生类中的访问级别。3. 继承方式与成员访问控制继承方式直接影响基类public、protected、private成员在派生类中的可见性。基类成员public 继承protected 继承private 继承publicpublicprotectedprivateprotectedprotectedprotectedprivateprivate不可访问不可访问不可访问三种继承方式的特点3.1 public 继承最常用基类的 public 成员在派生类中仍为 public。基类的 protected 成员在派生类中仍为 protected。体现is-a关系派生类是基类的一种。3.2 protected 继承所有基类的 public 和 protected 成员在派生类中都变为 protected。通常用于实现层面的继承而不是接口继承。3.3 private 继承所有基类成员在派生类中都变为 private。体现is-implemented-in-terms-of根据基类实现的关系更接近于组合。在决定使用 private 继承时应优先考虑组合composition。4. 派生类的构造与析构4.1 构造顺序先调用基类的构造函数按继承顺序从左到右。再按照类中成员声明的顺序初始化成员对象包括成员变量和子对象。最后执行派生类的构造函数体。4.2 析构顺序与构造完全相反先执行派生类的析构函数体然后析构成员对象最后调用基类的析构函数。4.3 显式调用基类构造函数cppclass Base { public: Base(int x) : data(x) {} private: int data; }; class Derived : public Base { public: Derived(int x, int y) : Base(x), derivedData(y) {} private: int derivedData; };注意如果基类没有默认构造函数派生类的每个构造函数必须在初始化列表中显式调用基类的某构造函数。5. 成员覆盖与隐藏5.1 函数覆盖override派生类可以重新定义基类中已有的非虚成员函数这叫隐藏hiding对于虚函数重新定义称为覆盖override是实现多态的基础。cppclass Base { public: virtual void func() { cout Base::func()\n; } void other() { cout Base::other()\n; } }; class Derived : public Base { public: virtual void func() override { cout Derived::func()\n; } // 覆盖 void other() { cout Derived::other()\n; } // 隐藏 };5.2override关键字C11显式标记派生类的虚函数要覆盖基类的虚函数。如果基类没有对应的虚函数编译会报错避免意外创建新函数。5.3final关键字C11final用在类禁止其他类继承该类。final用在虚函数禁止派生类再覆盖该虚函数。cppclass Base final { }; // 不可以被继承 class Base2 { virtual void func() final; // 派生类不可覆盖 func };6. 多继承Multiple InheritanceC 支持一个派生类同时继承多个基类。cppclass A { }; class B { }; class C : public A, public B { };6.1 二义性问题如果多个基类含有同名成员派生类访问时必须使用作用域运算符明确指定来自哪个基类。cppclass A { public: void f(); }; class B { public: void f(); }; class C : public A, public B { void call() { A::f(); // 明确调用 A 的 f B::f(); } };6.2 菱形继承问题textBase / \ A B \ / Derived如果 A 和 B 都继承自 BaseDerived 多重继承 A 和 B会导致两份 Base 的副本访问 Base 成员时产生二义性并且构造和析构次序也变得复杂。解决方案虚继承virtual inheritance。7. 虚继承虚继承确保在菱形继承中最顶层的基类只被保留一份共享副本。cppclass Base { }; class A : virtual public Base { }; class B : virtual public Base { }; class Derived : public A, public B { };7.1 构造顺序虚继承虚基类的构造函数优先于非虚基类。虚基类只在最终派生类的构造函数中被初始化一次。所有虚基类按照它们出现在继承列表中的顺序初始化再按普通继承顺序。7.2 虚继承的代价增加了间接访问和内存开销通常通过虚基类指针表。构造和析构规则复杂应谨慎使用。8. 继承与多态多态基类指针或引用指向派生类对象通过虚函数调用实际类型的成员。虚函数表vtable每个含有虚函数的类都有一个虚函数表通过虚指针vptr访问。纯虚函数与抽象类virtual void func() 0;表示纯虚函数。含有纯虚函数的类称为抽象类不能实例化。派生类必须实现所有纯虚函数否则也是抽象类。cppclass Shape { public: virtual void draw() 0; }; class Circle : public Shape { public: void draw() override { /* 绘制圆形 */ } };9. 继承与访问控制总结成员访问性在类内部在派生类内部public 继承在外部通过对象private✔✘✘protected✔✔✘public✔✔✔protected成员的引入正是为了支持继承允许派生类访问但禁止外部访问。在类的设计中通常将数据成员设为 private而将需要被派生类定制的方法设为 protected 或 public virtual。10. 最佳实践与建议优先使用 public 继承只有当确实需要实现层面的隔离时才考虑 private/protected 继承。析构函数应为 virtual如果通过基类指针删除派生类对象基类的析构函数必须是虚函数否则会产生未定义行为只调用基类析构函数。避免过深的继承层次多层继承增加理解难度和耦合度优先考虑组合而不是继承Composition over Inheritance。使用override和final明确虚函数覆盖意图增加代码安全性。尽量不使用多继承除非必要如果必须使用注意避免菱形继承和名字冲突。虚继承只在解决菱形继承时使用不要滥用。11. 一个完整示例cpp#include iostream using namespace std; class Animal { public: Animal(const string n) : name(n) {} virtual void speak() const { cout Animal name speaks. endl; } virtual ~Animal() default; // 虚析构 protected: string name; }; class Dog : public Animal { public: Dog(const string n) : Animal(n) {} void speak() const override { cout Dog name barks. endl; } }; class Cat : public Animal { public: Cat(const string n) : Animal(n) {} void speak() const override { cout Cat name meows. endl; } }; int main() { Animal* zoo[2]; zoo[0] new Dog(Buddy); zoo[1] new Cat(Kitty); for (auto a : zoo) a-speak(); for (auto a : zoo) delete a; return 0; }输出textDog Buddy barks. Cat Kitty meows.12. 总结C 的继承机制功能强大而灵活它支持单继承、多继承、虚继承并提供了不同的访问控制级别。正确使用继承可以提高代码的复用性和可扩展性但滥用继承会导致设计复杂、维护困难。理解继承的底层语义尤其是对象模型、构造/析构顺序、虚函数机制是成为 C 高手的重要一步。在实际工程中应牢记组合优先于继承继承用于表达稳定的“is-a”关系当关系不明确时组合往往带来更低的耦合。

相关文章:

C++ 继承完全指南

1. 概述继承(Inheritance)是面向对象编程的三大特性之一(封装、继承、多态)。在 C 中,继承允许我们创建一个新类(派生类, derived class)基于另一个已有的类(基类&#x…...

Boardcon LGA3576模块:嵌入式AI与多媒体处理实战解析

1. Boardcon LGA3576系统模块深度解析 在嵌入式系统开发领域,选择一款性能强劲且接口丰富的系统模块(SoM)往往能大幅缩短产品开发周期。最近Boardcon推出的LGA3576模块引起了我的注意,这款采用Rockchip RK3576 AI SoC的模块在性能…...

安全施工日志软件适合哪些工程企业?先看安全是不是要放到一条业务线上

一、三个最常见的误区:以为日志是终点,其实它只是起点安全施工日志在很多项目上被当成“安全员的个人工作记录”。早上去现场转一圈,在本子上记几条问题,有空了誊到电子版里,月底归档交上去。看起来该做的事都做了&…...

SBP预训练技术:合成数据优化与低资源场景实践

1. 项目背景与核心价值SBP(Synthetic-Boosted Pretraining)是当前预训练领域的前沿方向之一,它通过合成数据优化技术显著提升模型在低资源场景下的表现。我在最近三个月的项目实践中发现,合理的合成数据策略能使BERT类模型在小样本…...

扩散模型在多模态触觉图像生成中的应用与优化

1. MultiDiffSense:基于扩散模型的多模态触觉图像生成技术解析在机器人感知领域,触觉-视觉多模态数据对齐一直是提升交互能力的关键挑战。传统方法需要依赖昂贵的硬件设备和耗时的数据采集流程,而单模态生成模型又难以满足跨模态学习的需求。…...

华为应用生成 .p12、.cer、.p7b

打开 DevEco Studio。找到生成签名文件的入口,常见是 Build > Generate Key and CSR。生成两个文件:.p12:私钥库,自己保存好,不能丢。.csr:证书请求文件,上传到你截图这个位置。密码&#xf…...

不只是system分区:为RK3588配置完整的A/B无缝升级分区列表(以Android 12为例)

不只是system分区:为RK3588配置完整的A/B无缝升级分区列表(以Android 12为例) 当你在RK3588平台上为Android 12配置A/B系统升级时,是否遇到过这样的场景:基础编译一切顺利,却在生成OTA包时突然遭遇Cannot f…...

后端程序员视角:拆解一个高并发登录接口的设计,从Redis Token管理到防重复注册

高并发登录接口设计实战:从Redis会话管理到防刷注册 移动互联网时代,一个看似简单的登录按钮背后,往往隐藏着复杂的系统设计考量。去年双十一期间,某头部社交平台登录接口峰值QPS突破50万,而整个过程中用户感知到的只是…...

异步爬虫框架设计:从插件化架构到反爬策略实战

1. 项目概述:从标题到实战,一个开源项目的深度解构看到etticat/clawhark这个项目标题,很多开发者可能会心一笑。这又是一个典型的“个人开发者/组织名 项目名”的 GitHub 仓库命名方式。etticat是作者或组织的标识,而clawhark这个…...

深入RK809 PMIC:除了电量计,这颗RK3568的‘电源管家’还能做什么?

深入RK809 PMIC:解锁RK3568电源管理的隐藏技能 当工程师们谈论RK3568平台时,RK809这颗集成PMIC常常被简化为"电池电量计"的角色。但在这颗仅有55mm大小的芯片内部,实际上藏着一个完整的电源管理系统。就像瑞士军刀不止有主刀片一样…...

从日志时间戳到定时任务:Linux date命令在运维监控中的7个高频用法(附脚本片段)

从日志时间戳到定时任务:Linux date命令在运维监控中的7个高频用法(附脚本片段) 在Linux系统运维的日常工作中,时间管理从来都不是简单的"看一眼时钟"那么简单。当服务器集群跨越多个时区,当应用程序日志采用…...

通过 OpenClaw 配置 Taotoken 实现自动化 Agent 工作流

通过 OpenClaw 配置 Taotoken 实现自动化 Agent 工作流 1. 准备工作 在开始配置 OpenClaw 与 Taotoken 的集成前,需要确保已完成以下基础准备。首先登录 Taotoken 控制台,在「API 密钥」页面创建新的访问密钥。建议为 OpenClaw 单独创建密钥以便后续权…...

别再只调参了!用Deeplabv3+做自动驾驶分割,这3个工程化细节(特征融合、ASPP裁剪、通道数调整)比换模型更重要

Deeplabv3自动驾驶分割实战:3个被低估的工程化调优策略 当我们在自动驾驶项目中部署语义分割模型时,常常陷入一个误区——认为模型性能的提升只能通过更换更大规模的预训练模型或调整超参数来实现。实际上,在Deeplabv3这类成熟架构中&#xf…...

新手入门教程使用python在五分钟内接入taotoken大模型

新手入门教程:使用Python在五分钟内接入Taotoken大模型 1. 注册Taotoken并获取API密钥 要开始使用Taotoken的大模型API,首先需要注册账号并获取API密钥。访问Taotoken官网,完成注册流程后,登录控制台。在控制台的API密钥管理页面…...

别再只用gzip了!实测Vite+Vue项目启用Brotli压缩,打包体积再瘦身30%

前端性能优化实战:用Brotli压缩技术为Vite项目瘦身 在追求极致用户体验的今天,前端性能优化已成为开发者必修课。当我们已经用尽代码分割、懒加载、Tree Shaking等常规手段后,还有哪些"隐藏技能"能进一步提升应用性能?本…...

体验在低功耗设备上通过统一API调用Claude与GPT模型的便捷性

体验在低功耗设备上通过统一API调用Claude与GPT模型的便捷性 1. 低功耗设备上的开发挑战 在arm7等低功耗设备上进行大模型应用开发时,传统方式需要为每个模型厂商单独集成SDK,这不仅占用宝贵的存储空间,还可能因架构差异导致兼容性问题。我…...

基于MCF51CN128的串口转以太网桥接方案设计与实现

1. 项目概述在工业控制和物联网领域,大量传统设备仍依赖串口通信(如RS232/485),而现代网络化需求日益增长。基于MCF51CN128微控制器和FreeRTOS的串口转以太网桥接方案,正是解决这一痛点的关键技术。该方案通过硬件协议…...

3D场景自动生成与优化:NavMesh与智能分解技术

1. 项目背景与核心价值在游戏开发和虚拟仿真领域,3D场景的构建与优化一直是耗时的核心工作。传统手工建模方式需要美术人员逐个摆放场景元素,不仅效率低下,而且难以保证场景的合理性和可导航性。我们团队在最近的项目中研发了一套从自动导航网…...

长期使用中感受Taotoken聚合端点的高可用与容灾保障

长期使用中感受Taotoken聚合端点的高可用与容灾保障 1. 业务连续性的挑战与需求 在构建依赖大模型能力的应用服务时,确保API调用的高可用性是一个关键挑战。上游供应商的服务波动、区域故障或突发流量限制都可能对业务连续性造成影响。我们团队在过去六个月的生产…...

提升测试效率:用快马快速构建openclaw等软件的自动化卸载测试工具

提升测试效率:用快马快速构建openclaw等软件的自动化卸载测试工具 在软件开发过程中,卸载功能的测试往往容易被忽视,但实际上它直接影响着用户体验。想象一下,用户想要卸载你的软件时,如果遇到残留文件、注册表项无法…...

TI AM62A/AM68A/AM69A视觉处理器解析与边缘AI应用

1. TI AM62A/AM68A/AM69A视觉处理器深度解析德州仪器(TI)最新发布的AM62A、AM68A和AM69A系列Arm Cortex视觉处理器,标志着边缘AI计算进入了一个新的阶段。这三款处理器采用16nm FinFET工艺,从单核Cortex-A53到八核Cortex-A72的配置…...

终极指南:专业配置Mem Reduct中文界面,释放Windows内存管理潜力

终极指南:专业配置Mem Reduct中文界面,释放Windows内存管理潜力 【免费下载链接】memreduct Lightweight real-time memory management application to monitor and clean system memory on your computer. 项目地址: https://gitcode.com/gh_mirrors/…...

Spartan-3 FPGA设计优化与成本控制实战

1. Spartan-3 FPGA设计优化实战:用Synplify Pro实现成本控制在2006年的FPGA设计领域,Xilinx Spartan-3系列的出现彻底改变了中低端应用的硬件开发生态。作为一名经历过那个时代的技术人员,我亲眼见证了这款器件如何将原本需要ASIC实现的复杂功…...

自监督学习在医学影像分割中的样本高效之道:从理论到实战

目录 引言:标注稀缺困境下的新思路 自监督学习原理:教模型认识“医学解剖学” 为什么自监督学习对医学影像特别有效? 核心前置任务设计 对比学习方法 掩码图像建模 几何约束预训练 如何评估自监督预训练的质量? 代码实战:从头构建一个自监督预训练+微调的分割系统…...

TaskbarX终极指南:42种动画效果打造Windows任务栏完美居中体验

TaskbarX终极指南:42种动画效果打造Windows任务栏完美居中体验 【免费下载链接】TaskbarX Center Windows taskbar icons with a variety of animations and options. 项目地址: https://gitcode.com/gh_mirrors/ta/TaskbarX 想让你的Windows桌面焕然一新&am…...

AS5600磁编码器IIC驱动踩坑实录:从器件无响应到角度跳变的5个常见问题解决

AS5600磁编码器IIC驱动实战避坑指南:5个典型问题深度解析 磁编码器在工业自动化、机器人关节控制等场景中的应用越来越广泛,而AS5600凭借其非接触式设计和12位高分辨率成为许多工程师的首选。但在实际项目落地过程中,从硬件布局到软件调试的每…...

UE5 GAS实战避坑:从GE/GA/GC配置面板的隐藏细节,到多人联机同步的正确姿势

UE5 GAS实战避坑指南:从配置陷阱到联机同步的深度解析 在虚幻引擎5的多人游戏开发中,GameplayAbilitySystem(GAS)就像一把双刃剑——用好了能让你的战斗系统行云流水,用不好则会让团队在联机调试中痛不欲生。我经历过三…...

从零部署私有ChatGPT服务:技术架构、安全实践与成本控制

1. 项目概述:从零到一部署一个专属的ChatGPT对话服务最近在GitHub上看到一个挺有意思的项目,叫“DouDOU-start/chatgpt-register-deploy”。光看名字,你大概能猜到它想做什么:帮你搞定ChatGPT的注册和部署。但如果你以为这只是个简…...

告别C盘权限烦恼:在D盘搭建3ds Max 2023 SDK + VS2019 + QT开发环境全流程

告别C盘权限烦恼:在D盘搭建3ds Max 2023 SDK VS2019 QT开发环境全流程 当你在Windows系统上尝试搭建3ds Max插件开发环境时,是否经常遇到C盘权限不足、路径混乱导致的编译失败?本文将带你从零开始,在D盘构建一套完整的开发环境&…...

别再手动点鼠标了!用Python脚本5分钟搞定GeoServer上百个图层发布(附完整代码)

GeoServer自动化发布实战:Python脚本解放GIS工程师的双手 当你面对一个存有数百个shp、tif文件的文件夹时,是否感到无从下手?传统的手动发布方式不仅耗时耗力,还容易出错。本文将带你探索如何用Python脚本5分钟搞定GeoServer上百个…...