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

c++类派生2

一、派生类与基类的构造函数关系构造函数的作用是初始化对象的成员。派生类对象包含基类子对象和派生类新增子对象两部分因此派生类构造时必须先初始化基类子对象再初始化自身新增成员。核心规则默认行为派生类的构造函数无论无参还是有参默认自动调用基类的无参构造函数。显式调用有参构造如果基类没有无参构造仅定义了有参构造或者需要用特定参数初始化基类成员必须在派生类构造函数的初始化列表中显式调用基类的有参构造函数。执行顺序基类构造函数 → 派生类成员对象的构造函数若有 → 派生类构造函数体。示例代码#include iostream #include string using namespace std; // 基类人 class Person { protected: string name; int age; public: // 基类无参构造 Person() : name(未知), age(0) { cout Person 无参构造函数执行 endl; } // 基类有参构造 Person(string n, int a) : name(n), age(a) { cout Person 有参构造函数执行 name , age endl; } }; // 派生类学生 class Student : public Person { private: string id; // 学号派生类新增成员 public: // 1. 派生类无参构造默认调用基类无参构造 Student() : id(000000) { cout Student 无参构造函数执行 endl; } // 2. 派生类有参构造显式调用基类有参构造初始化继承的成员 Student(string n, int a, string i) : Person(n, a), id(i) { cout Student 有参构造函数执行学号 id endl; } void show() { cout 姓名 name 年龄 age 学号 id endl; } }; int main() { cout 创建无参学生对象 endl; Student s1; s1.show(); cout \n 创建有参学生对象 endl; Student s2(张三, 18, 2024001); s2.show(); return 0; }输出结关键说明如果基类只定义了有参构造没有无参构造派生类构造函数必须在初始化列表显式调用基类有参构造否则编译报错。初始化列表的执行顺序只与成员声明顺序有关与初始化列表中书写顺序无关基类构造永远先于派生类。二、派生类与基类的析构函数关系析构函数的作用是释放对象占用的资源其执行顺序与构造函数完全相反先清理派生类自身的资源再清理基类子对象的资源。核心规则派生类的析构函数执行完毕后自动调用基类的析构函数。析构函数没有参数因此无法重载也不需要在派生类析构中显式调用基类析构编译器自动完成。重要当用基类指针 / 引用指向派生类对象时必须将基类析构函数声明为virtual虚析构函数否则删除对象时只会调用基类析构导致派生类资源泄漏。示例代码基于上例扩展// 给Person和Student添加析构函数 class Person { // ... 其他成员不变 public: ~Person() { cout Person 析构函数执行 name endl; } }; class Student : public Person { // ... 其他成员不变 public: ~Student() { cout Student 析构函数执行学号 id endl; } }; int main() { cout 创建有参学生对象 endl; Student s(李四, 20, 2024002); s.show(); cout 对象即将销毁 endl; return 0; // 程序结束时自动销毁局部对象 }输出结果 创建有参学生对象 Person 有参构造函数执行李四, 20 Student 有参构造函数执行学号2024002 姓名李四年龄20学号2024002 对象即将销毁 Student 析构函数执行学号2024002 Person 析构函数执行李四三、派生类与基类的拷贝构造函数关系拷贝构造函数用于用一个已存在的对象初始化新对象继承体系中拷贝构造的执行逻辑与普通构造类似。核心规则默认行为派生类的默认拷贝构造函数会自动调用基类的拷贝构造函数完成基类子对象的拷贝。显式定义派生类拷贝构造如果手动定义派生类的拷贝构造函数编译器默认调用基类的无参构造函数而非拷贝构造此时必须在初始化列表中显式调用基类的拷贝构造否则基类成员会被默认初始化导致数据丢失。示例代码#include iostream #include string using namespace std; class Person { protected: string name; int age; public: Person(string n, int a) : name(n), age(a) {} // 基类拷贝构造 Person(const Person p) : name(p.name), age(p.age) { cout Person 拷贝构造执行 endl; } void show() { cout name , age; } }; class Student : public Person { private: string id; public: Student(string n, int a, string i) : Person(n, a), id(i) {} // 错误写法显式定义派生类拷贝构造未调用基类拷贝构造 // Student(const Student s) : id(s.id) { // cout Student 拷贝构造执行错误版 endl; // } // 正确写法显式调用基类拷贝构造 Student(const Student s) : Person(s), id(s.id) { cout Student 拷贝构造执行正确版 endl; } void show() { Person::show(); cout , 学号 id endl; } }; int main() { Student s1(王五, 19, 2024003); cout 原对象; s1.show(); cout \n拷贝生成新对象 endl; Student s2(s1); // 调用拷贝构造 cout 新对象; s2.show(); return 0; }输出结果正确版原对象王五, 19, 学号2024003 拷贝生成新对象 Person 拷贝构造执行 Student 拷贝构造执行正确版 新对象王五, 19, 学号2024003错误版输出对比如果使用注释中的错误写法输出会变成原对象王五, 19, 学号2024003 拷贝生成新对象 Student 拷贝构造执行错误版 新对象, 0, 学号2024003可以看到基类的name和age被默认初始化空字符串和 0数据完全丢失。四、派生类与基类的赋值运算符重载关系赋值运算符重载用于对象之间的赋值操作其继承规则与拷贝构造类似但需要手动处理基类部分的赋值。核心规则默认行为派生类的默认赋值运算符重载函数会自动调用基类的赋值运算符完成基类子对象的赋值。显式定义派生类赋值重载如果手动定义派生类的赋值运算符编译器不会自动调用基类的赋值运算符必须通过基类名::operator显式调用否则基类成员不会被正确赋值。赋值重载需要遵循自赋值检查和返回自身引用的通用规则。示例代码#include iostream #include string using namespace std; class Person { protected: string name; int age; public: Person(string n, int a) : name(n), age(a) {} // 基类赋值运算符重载 Person operator(const Person p) { if (this ! p) { // 自赋值检查 name p.name; age p.age; cout Person 赋值运算符执行 endl; } return *this; } void show() { cout name , age; } }; class Student : public Person { private: string id; public: Student(string n, int a, string i) : Person(n, a), id(i) {} // 派生类赋值运算符重载 Student operator(const Student s) { if (this ! s) { // 自赋值检查 Person::operator(s); // 显式调用基类赋值运算符 id s.id; // 赋值派生类新增成员 cout Student 赋值运算符执行 endl; } return *this; } void show() { Person::show(); cout , 学号 id endl; } }; int main() { Student s1(赵六, 21, 2024004); Student s2(临时, 0, 000000); cout 赋值前s2; s2.show(); s2 s1; // 调用赋值运算符 cout 赋值后s2; s2.show(); return 0; }输出结果赋值前s2临时, 0, 学号000000 Person 赋值运算符执行 Student 赋值运算符执行 赋值后s2赵六, 21, 学号2024004关键说明如果注释掉Person::operator(s);赋值后 s2 的name和age仍为 临时 和 0只有id被正确赋值。五、静态成员的继承性静态成员属于类本身而非某个对象存储在静态全局区整个程序中只有一份副本。继承体系中静态成员的规则如下核心规则共享性基类的静态成员被所有派生类共享无论派生多少层静态成员只有一份。访问性派生类可以直接访问基类的公有 / 保护静态成员访问方式为基类名::静态成员或派生类名::静态成员效果相同。隐藏性派生类可以定义与基类同名的静态成员此时派生类的静态成员会隐藏基类的同名静态成员通过作用域解析符::仍可访问基类版本。示例代码#include iostream using namespace std; class Base { public: static int count; // 基类静态成员变量 static void showCount() { // 基类静态成员函数 cout Base::count count endl; } }; int Base::count 0; // 静态成员类外初始化 class Derived : public Base { public: static int count; // 派生类重定义同名静态成员隐藏基类版本 static void showCount() { // 派生类重定义同名静态函数 cout Derived::count count endl; cout Base::count Base::count endl; // 显式访问基类静态成员 } }; int Derived::count 100; // 派生类静态成员初始化 int main() { // 基类静态成员访问 Base::count 10; Base::showCount(); // 输出 Base::count 10 // 派生类访问基类静态成员 Derived::Base::showCount(); // 输出 Base::count 10 cout 通过Derived访问Base::count Derived::Base::count endl; // 派生类自身静态成员 Derived::showCount(); // 输出 Derived::count 100 和 Base::count 10 // 验证共享性修改基类静态成员所有派生类都能看到 Base::count 20; Derived::showCount(); // 输出 Base::count 20 return 0; }输出结果plaintextBase::count 10 Base::count 10 通过Derived访问Base::count 10 Derived::count 100 Base::count 10 Derived::count 100 Base::count 20六、友元的继承性友元的作用是让外部函数 / 类访问类的私有 / 保护成员但友元关系不具有继承性。核心规则基类的友元不能直接访问派生类的私有 / 保护成员除非派生类显式声明该函数 / 类为自己的友元。基类的友元可以访问派生类中从基类继承的成员如果该成员在基类中是公有的或友元通过基类指针 / 引用访问。示例代码#include iostream #include string using namespace std; class Derived; // 前向声明 class Base { private: int base_private; protected: int base_protected; public: Base(int a, int b) : base_private(a), base_protected(b) {} friend void showBase(const Base b); // 声明友元函数 }; class Derived : public Base { private: int derived_private; // 派生类私有成员 public: Derived(int a, int b, int c) : Base(a, b), derived_private(c) {} // 如果取消下面注释友元函数就能访问derived_private // friend void showBase(const Base b); }; // 友元函数实现 void showBase(const Base b) { cout 基类私有成员 b.base_private endl; cout 基类保护成员 b.base_protected endl; // 错误友元不能访问派生类的私有成员 // const Derived d static_castconst Derived(b); // cout 派生类私有成员 d.derived_private endl; } int main() { Derived d(10, 20, 30); showBase(d); // 派生类对象可以传给基类引用友元能访问基类部分 return 0; }输出结果基类私有成员10 基类保护成员20如果取消注释中访问derived_private的代码编译会报错因为showBase是 Base 的友元不是 Derived 的友元。七、final 类最终类final是 C11 引入的关键字用于修饰类或虚函数核心作用是禁止继承或重写。核心规则final 类在类名后加final关键字表示该类不能被任何类继承。final 虚函数在虚函数声明后加final表示该虚函数不能在派生类中被重写覆盖。示例代码#include iostream using namespace std; // final类不能被继承 class FinalClass final { public: void show() { cout 这是final类的成员函数 endl; } }; // 错误不能继承final类 // class Derived : public FinalClass {}; class Base { public: virtual void func() final { // final虚函数不能被重写 cout Base::func() final函数 endl; } }; class Derived : public Base { public: // 错误不能重写final虚函数 // void func() override { cout Derived::func() endl; } }; int main() { FinalClass fc; fc.show(); Base b; b.func(); return 0; }关键说明final 类通常用于设计不希望被扩展的类比如工具类、封装好的底层类防止错误继承破坏类的封装性。final 虚函数用于锁定基类的某个行为确保派生类不能修改该行为的实现。

相关文章:

c++类派生2

一、派生类与基类的构造函数关系构造函数的作用是初始化对象的成员。派生类对象包含基类子对象和派生类新增子对象两部分,因此派生类构造时必须先初始化基类子对象,再初始化自身新增成员。核心规则默认行为:派生类的构造函数(无论…...

如何高效解锁艾尔登法环帧率限制:专业玩家的完整配置指南

如何高效解锁艾尔登法环帧率限制:专业玩家的完整配置指南 【免费下载链接】EldenRingFpsUnlockAndMore A small utility to remove frame rate limit, change FOV, add widescreen support and more for Elden Ring 项目地址: https://gitcode.com/gh_mirrors/el/…...

Claude最新金融智能体模板到底能做什么?一文看懂真实业务场景

Claude最新发布的10大金融智能体模板,在金融科技圈引发了不小关注。原因并不只是它能够生成报告、总结财报,而是它第一次以“业务角色”的形式进入金融流程。无论是Pitch Builder、Earnings Reviewer,还是KYC Screener,本质上都已…...

流域生态系统碳排放、碳循环模拟与评估技术应用

随着全球气候变化的加剧,碳中和已成为实现可持续发展的重要目标之一。碳中和不仅仅是能源和工业领域的调整,它涉及整个生态系统的转型与再生。在这一过程中,流域的生态系统作为水、土、生物多样性等自然资源的集成体,扮演着至关重…...

TV Bro电视浏览器终极指南:如何在智能电视上享受免费开源的大屏上网体验

TV Bro电视浏览器终极指南:如何在智能电视上享受免费开源的大屏上网体验 【免费下载链接】tv-bro Simple web browser for android optimized to use with TV remote 项目地址: https://gitcode.com/gh_mirrors/tv/tv-bro TV Bro是一款专为智能电视和遥控器操…...

青年科学基金 PPT 定制|绎奇演示专业打磨 助力立项突围

青年科学基金申报的老师看过来? 一份逻辑清晰、排版高级的申报 PPT真的太影响评审第一印象了!青年科学基金申报答辩 PPT 是展现科研实力、项目价值与个人学术素养的核心载体,普通通用模板千篇一律、套路固化,难以贴合自身研究方向与申报评审…...

应届生编程面试,这8个加分项,让你在面试官面前脱颖而出

文章目录前言一、基础扎实:别死背八股,要懂“为什么”1. 经典技术永不过时,别盲目追新2. 把“是什么”变成“为什么”,才是真的懂二、项目经历:不说技术栈,说“解决了什么问题”1. 用数据说话,量…...

11个系统、8000张表,这家环保集团如何让沉睡的数据真正“用起来”

很多大型集团企业都有过这样一段经历:信息化建设做了好几轮,ERP上线了,OA部署了,生产监控系统也跑起来了,业务数据越积越厚——看起来数字化建设卓有成效。但真到需要数据的时候,才发现麻烦来了。财务要汇报…...

四川南充纺织减速机升级:从传统织机到智能传动

千年绸都的"心脏"正在换代南充,古称果州,素有"中国绸都"之美誉。从汉代丝绸之路的起点之一,到如今四川省重要的纺织产业基地,南充纺织业绵延两千余年。然而,支撑这一产业蓬勃发展的,不…...

本地从零部署 Java+Vue 前后端分离项目(超详细新手保姆级教程)

一、前言现在企业开发基本都是前后端分离架构,后端用 Java SpringBoot 提供接口、操作数据库,前端用 Vue 搭建页面、做交互展示。很多刚入门的同学,单独跑后端、单独跑前端都没问题,但本地联调对接接口时,总会遇到跨域…...

开发AI Agent时利用Taotoken实现多模型路由与降级策略

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 开发AI Agent时利用Taotoken实现多模型路由与降级策略 1. 场景与挑战 在构建复杂的AI Agent时,开发者常常面临一个核心…...

终极指南:如何在Windows上安装APK文件?3分钟学会跨平台应用安装

终极指南:如何在Windows上安装APK文件?3分钟学会跨平台应用安装 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否想在Windows电脑上直接运…...

LyricsX:macOS歌词同步的终极解决方案

LyricsX:macOS歌词同步的终极解决方案 【免费下载链接】LyricsX 🎶 Ultimate lyrics app for macOS. 项目地址: https://gitcode.com/gh_mirrors/ly/LyricsX 还在为macOS上找不到好用的歌词应用而烦恼吗?LyricsX为你带来了一站式的智能…...

抖音下载器终极指南:3分钟学会免费下载无水印视频和音乐

抖音下载器终极指南:3分钟学会免费下载无水印视频和音乐 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback sup…...

长期使用Taotoken的Token Plan套餐带来的成本体感变化

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 长期使用Taotoken的Token Plan套餐带来的成本体感变化 在AI应用开发中,成本控制与预算可预测性是项目持续运营的关键。…...

保姆级教程:在Windows Server上为SQL Server 2012彻底搞定SQLNCLI11驱动安装与注册

Windows Server环境下SQLNCLI11驱动全流程部署指南 当你在全新的Windows Server系统上部署SQL Server 2012后,准备配置链接服务器时,突然发现提供程序列表中缺少关键的SQLNCLI11驱动——这种场景对于许多运维工程师和初级DBA来说并不陌生。本文将带你深入…...

USB端口如何管控?分享五个管控USB端口的小技巧,建议学起来

在企业数字化办公的今天,USB接口既是便利的工具,也是数据泄露的“重灾区”。U盘病毒入侵、核心资料被拷贝等风险时刻威胁着内网安全。如何科学、有效地管理这些“不安分”的接口?以下为您分享五个USB端口管控技巧,您可以根据企业的…...

揭秘Midjourney底层图像编码协议:Rust逆向解析PNG元数据+动态DPI印相校准(含v6.2协议逆向日志)

更多请点击: https://intelliparadigm.com 第一章:Midjourney图像编码协议的演进与印相范式变革 Midjourney 的图像生成并非基于传统像素栅格的直接操作,而是依托一套动态演化的隐式编码协议——该协议将文本提示(prompt&#x…...

CISP认证报考必看:从考完到出分、查证、续证一文说清

今天,这篇主要关于CISP出成绩、查成绩和有效期的干货,今天结合官方规则和常见情况说清楚,省得大家瞎等。一、CISP是什么?报考条件如何?在深入流程之前,先简单说下CISP的定位。CISP由中国信息安全测评中心&a…...

软件测试新人必看:入职前3个月如何快速站稳脚跟

对于软件测试新人而言,入职前3个月是职业发展的关键奠基期。这一阶段不仅要完成从校园到职场的身份转变,更要快速掌握专业技能、融入团队节奏,为后续的职业发展筑牢根基。本文将从专业角度出发,为软件测试新人拆解入职前3个月的成…...

GNSS数据处理新手避坑:用GAMP_GOOD下载IGS/MGEX数据,从配置.cfg到成功运行的完整流程

GNSS数据处理实战:从GAMP_GOOD配置到IGS/MGEX数据高效下载全解析 当第一次打开GAMP_GOOD软件包时,很多GNSS领域的研究者都会感到既兴奋又困惑——这个被广泛推荐的下载工具确实能一站式获取IGS和MGEX数据,但配置文件的复杂性和报错信息的晦涩…...

从公司Logo到页码:手把手教你定制OrCAD标题栏模板并全局应用

从公司Logo到页码:手把手教你定制OrCAD标题栏模板并全局应用 在电子设计领域,标准化文档不仅是专业性的体现,更是团队协作效率的保障。想象一下,当客户打开来自同一公司的不同项目文档,看到的却是风格迥异的标题栏——…...

在Node.js后端服务中集成Taotoken调用大模型接口

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 在Node.js后端服务中集成Taotoken调用大模型接口 对于需要在后端服务中集成AI能力的Node.js开发者而言,直接对接多个大…...

博物馆科技馆迎来数字员工,AI数字人公司厂商助力展馆智慧升级

走进博物馆,你期待怎样的体验?是隔着玻璃看展品,还是听一段千篇一律的录音导览?如今,越来越多的场馆正在给出新的答案:一个能走、能说、能聊天的AI数字人,正悄然改变着“看展”这件事。过去几年…...

开源智能家居中枢搭建:从架构解析到自动化场景实践

1. 项目概述与核心价值最近在折腾智能家居中枢时,发现了一个挺有意思的开源项目,叫contextzero/nest_hub。乍一看名字,很容易让人联想到谷歌的 Nest Hub 智能显示屏,但深入探究后,你会发现它其实是一个旨在“模拟”或“…...

收藏必备!小白程序员轻松入门大模型:RAG效果调优全攻略

收藏必备!小白程序员轻松入门大模型:RAG效果调优全攻略 本文深入解析RAG(检索增强生成)效果调优,强调上下文质量对大模型回答的关键作用。文章指出,上下文召回率和准确率是调优的关键指标,分别对…...

教育 SaaS 供应链勒索攻击机理与闭环防御研究 —— 以 Canvas 数据泄露事件为例

摘要 2026 年 5 月,教育科技企业 Instructure 旗下 Canvas 学习管理系统遭遇 ShinyHunters 黑客组织攻击,3.65TB 数据遭窃取,波及近 9000 家教育机构、2.75 亿条用户记录,攻击者通过 Free‑for‑Teacher 环境工单相关漏洞获取初始…...

一年从5%到40%!AI嵌入企业应用,哪些白领岗位正在消失?

一年翻8倍:企业应用AI智能体比例飙升背后的岗位消失潮高德纳咨询最新数据显示,2026年企业应用中嵌入AI智能体的比例已达40%,而2025年这个数字还不足5%,一年时间翻了8倍。这一惊人的增长背后,众多白领岗位正在悄悄消失。…...

AI 与钓鱼即服务重构电子邮件威胁格局及防御体系研究

摘要 2026 年电子邮件威胁呈现工业化、智能化、隐蔽化演进趋势,钓鱼攻击占恶意邮件活动比例达 48%,90% 的大规模钓鱼活动依托钓鱼即服务(Phishing‑as‑a‑Service, PhaaS)平台开展,攻击载荷从传统文件型恶意代码转向 …...

3步解锁自动化:Elsevier Tracker智能追踪工具完全指南

3步解锁自动化:Elsevier Tracker智能追踪工具完全指南 【免费下载链接】Elsevier-Tracker 项目地址: https://gitcode.com/gh_mirrors/el/Elsevier-Tracker 在科研投稿的漫长等待中,每一次手动刷新Elsevier投稿系统都像是在黑暗中摸索。Elsevier…...