面向对象程序设计有4个主要特点:抽象,封装,继承和多态。
1.1继承与派生的概念
在C++中可重用性是通过继承(inheritance)这一机制来实现的。继承是C++的一个只要组成部分.
一个新类从已有的父类那里获得其已有特征,这种现象称为类的继承。通过继承,一个新建子类从已有的父类那里获得父类的特性。
从另一个角度说,从已有的类(父类)产生一个新的子类,称为类的派生。
类的继承是用已有的类来简历专用类的编程技术.
派生类继承了基类的所有数据成员和成员函数,并可以对成员做必要的增加和调整。
一个基类可以派生出多个派生类,每一个派生类又可以作为基类再派生出新的派生类,因此基类和派生类是相对而言的.
一个派生类不仅可以从一个基类派生,也可以从多个基类派生。一个派生类有两个或者多个基类的称为多重继承(multiple inheritance)。
关于派生类和基类的关系,可以表述为:派生类是基类的具体化,而基类则是派生类的抽象。
继承方式包括:public(公用的),private(私有的),protected(保护的).此项是可选的,如果不写此项,则默认是private的。
派生类从基类接收成员,派生类把基类全部的成员(不包括构造函数和析构函数)接手过来,也就是说是没有选择的,不能选择接收其中一部分成员,而舍弃另一部分成员.
不同继承方式决定了基类成员在派生类中的访问属性.
1)公用继承(public inheritance)
基类的公用成员和保护成员在派生类中保持原有访问属性,其私有成员仍为基类私有。
2)私有继承(private inheritance)
基类的公有成员和保护成员在派生类中成了私有成员,其私有成员仍为基类私有。
3)受保护的继承(protected inheritance)
基类的公用成员和保护成员在派生类中成了保护成员,其私有成员仍为基类私有.
公用继承:
采用公用继承方式时,基类的公用成员和保护成员在派生类中仍然保持其公用成员和保护成员的属性,而基类的私有成员在派生类中并没有成为派生类的私有成员,它仍然是基类的私有成员,只有基类的成员函数可以应用它,而不能被派生类的成员函数应用,因此就成为派生类中的不可访问的成员。
私用继承
私有基类的公用成员和保护成员在派生类中的访问属性相当于派生类中的私有成员,即派生类的成员函数能访问他们,而在派生类不能访问他们。私有基类的私有成员在派生类中成为不可访问的成员,只有基类的成员函数可以应用他们.一个基类成员在基类中的访问属性和在派生类中的访问属性可能是不同的.
保护继承
如果基类声明了私有成员,那么任何派生类都是不能访问他们的,若希望在派生类中能访问他们,应当把它们声明为保护成员,如果一个类中声明了保护成员,就意味着该类可能要用作基类,在他的派生类中会访问这些成员
比较一下私有继承和保护继承,可以发现,在直接派生类中,以上两种继承方式的作用实际上是相同的;在类外不能访问任何成员,而在派生类中可以通过成员函数访问基类中的公用成员和保护成员。
在派生类中,成员有4种不同的访问属性:
1)公用的,派生类和派生类外都可以访问。
2)受保护的,派生类内可以访问,派生类外不能访问,其下一层的派生类可以访问。
3)私有的,派生类内可以访问,派生类外不能访问
4)不可访问的,派生类内和派生类外都不能访问。
派生类的构造函数和析构函数
用户在声明类时可以不定义构造函数,系统会自动设置一个默认的构造函数,在定义类对象时会自动调用这个默认的构造函数。这个构造函数实际上是一个空函数,不执行任何操作,如果需要对类中的数据成员初始化,应自己定义构造函数。
构造函数的主要作用是对数据成员初始化,在设计派生类的构造函数时,不仅要考虑派生类所新增的数据成员的初始化,还应当考虑基类的数据成员初始化,也就是说,希望在执行派生类的构造函数时,使派生类的数据库成员和基类的数据成员同时都被初始化,解决这个问题的思路是:在执行派生类的构造函数时,调用基类的构造函数。
其一般形式为
派生类构造函数名(总参数列表):基类构造函数名(参数类别)
{派生类中新增数据成员初始化语句}
请注意:在类中对派生类构造函数作声明时,不包括基类构造函数名及其参数列表,只在定义函数时才将他们列出。
实际上,在派生类构造函数中对基类成员初始化,就是构造函数初始化表,也就是说,不仅可以利用初始化表对构造函数的数据成员初始化,而且可以利用初始化表调用派生类的基类构造函数,实现对基类数据成员的初始化。也可以在同一个构造函数的定义中同时实现这两种功能。
在建立一个对象时,执行构造函数的顺序是:派生类构造函数先调用基类的构造函数,再执行派生类构造函数本身(即派生类构造函数的函数体)
在派生类对象释放时,先执行派生类的析构函数,再执行基类的析构函数。
派生类构造函数的任务应该包括3个部分
对基类数据成员的初始化,对子对象数据成员初始化,对派生类数据成员初始化
程序中派生类构造函数首部如下:
Student1(int n,string nam,int n1,string nam1,int a,string ad):Student(n,nam),monotor(n1,nam1)
归纳起来,定义派生类构造函数的一般形式为
派生类构造函数名(总参数表列):基类构造函数名(参数表列),子对象名(参数表列)
{派生类中新增数据成员初始化语句}
执行派生类构造函数的顺序是:
调用基类构造函数,对基类数据成员初始化
调用子对象构造函数,对子对象数据成员初始化
再执行派生类构造函数本身,对派生类数据成员初始化。
派生类构造函数的总参数表列中的参数,应当包括基类构造函数和子对象的参数列表中的参数,基类构造函数和子对象的次序可以是任意的。如上面的派生类构造函数首部可以写成
Student(int n,string nam,int n1,string nam1,int a,stirng ad):monitor(n1,nam1),Student(n,nam)
如果在基类中没有定义构造函数,或者定义了没有参数的构造函数,那么在定义派生类构造函数时可以不写基类构造函数,因为此时派生类构造函数没有向基类构造函数传递参数的任务。调用派生类构造函数时系统自动首先调用基类的默认构造函数。如果基类和子对象类型的声明中都没有定义带参数的构造函数,而且也不需对派生类自己的数据成员初始化,则可以不必显示的定义派生类构造函数。因为此时派生类构造函数既没有像基类构造函数和子对象构造函数传递参数的任务,也没有对派生类数据成员初始化的任务。在建立派生类对象时,系统会自动调用系统提供的派生类的默认构造函数,并在执行派生类默认构造函数的过程中,调用基类的默认构造函数和子对象类型默认构造函数。
如果在基类或者子对象类型的声明中定义了才参数的构造函数,那么就必选显示的定义派生类构造函数,并在派生类构造函数中写出基类或子对象类型的构造函数及其参数。
如果在基类中既定义无参的构造函数,又定义了有参的构造函数(构造函数重载),则在定义派生类构造函数时,既可以包含基类构造函数及其参数,也可以不包含基类构造函数,在调用派生类构造函数时,根据构造函数的内容决定调用基类的有参构造函数还是无参构造函数。
派生类的析构函数
在执行派生类的析构函数时,系统会自动调用基类的析构函数和子对象的析构函数,对基类和子对象进行清理。调用的顺序和构造函数正好相反;先执行派生类自己的析构函数,对派生类新增加的成员进行清理,然后调用子对象的析构函数,对子对象进行清理,最后调用基类的析构函数,对基类进行清理.
声明多重继承的方法
如果已声明了类A,类B和类C,可以声明多重继承的派生类D:
class D:public A,private B,protected C
{类D新增加的成员}
多重继承派生类的构造函数形式于单继承时的构造函数形式基本相同,只有在初始表中包含多个基类构造函数
如
派生类构造函数名(总参数列表):基类1构造函数(参数类别),基类2构造函数(参数列表),基类3构造函数(参数列表)
{派生类中新增成员初始化}
各基类的排列顺序任意。派生类构造函数同样为:先调用基类的构造函数,再执行派生类构造函数的函数体.调用基类构造函数的顺序是按照声明派生类时基类出现的顺序.
多重继承一起的二义性问题
虚基类
虚基类的作用: 如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员,在引用这些同名成员时,必选在派生类对象名后增加直接基类名,以避免产生二义性,使其唯一地标识一个成员.
在一个类中 保留间接共同基类的多份同名成员,这种现象是人们不希望出现的。
C++提供虚基类(virtual base class)的方法,使得在继承间接共同基类时只保留一份成员.
现在,将类A声明为虚基类,方法如下
class A//声明基类A
{......};
class B:virtual public A//声明类B是类A的公用派生类,A是B的虚基类
{......};
class C:virtual public A//声明类C是类A的公用派生类,A是C的虚基类
{......};
注意:虚基类并不是声明基类时声明的,而是在声明派生类时,指定继承方式时声明的。因为一个基类可以在生成一个派生类时作为虚基类,而在声明另一个派生类时不作为虚基类,声明虚基类的一般形式为
class 派生类名:virtual 继承方式 基类名
经过这样的声明后,当基类通过多条派生路径被一个派生类继承时,该派生类只继承该基类一次。
需要注意:为了保证虚基类在派生类中只继承一次,应当在该基类的所有直接派生类中声明为虚基类,否则仍然会出现对基类的多次继承.
虚基类的初始化
C++编译系统只执行最后的派生类对虚基类的构造函数的调用,而忽略虚基类的其他派生类(如类B和类C)对虚基类的构造函数的调用,这就保证了虚基类的数据成员不会被多次初始化.
注意:在定义派生类的构造函数时,与以往使用的方法有所不同。规定:在最后的派生类中不仅仅要负责对其直接基类进行初始化,还要负责对虚基类初始化
使用多重继承时要十分小心,经常会出现二义性问题。许多专业人员认为:不要提倡在程序中使用多重继承,只有在比较简单和不易出现二义性的情况下或实在必要时才使用多重继承,能用单一继承解决的问题不要使用多重继承,也是由于这个原因,有些面向多谢的程序设计语言(如java,smalltalk)并不支持多重继承.
基类与派生类的转换
基类于派生类对象之间有赋值兼容关系,由于派生类中包含从基类继承的成员,因此可以将派生类的值赋给基类对象,在用到基类对象的时候可以其子类对象代替.
1)派生类对象可以向基类对象赋值。
如
A a1;//定义基类A对象a1
B b1;//定义类A的公用派生类B的对象b1
a1 = b1;//用派生类B对象b1对基类对象a1赋值
在赋值时舍弃派生类自己的成员,实际上,所谓赋值只是对数据成员赋值,对成员函数不存在赋值问题。
请注意:赋值后不能企图通过对象a1去访问派生类对象b1的成员,因为b1的成员于a1的成员是不同的。
应当注意,只能用子类对象对其基类对象赋值,而不能用基类对象对其之类对象赋值,理由是显然的,因为基类对象不包括派生类的成员,无法对派生类的成员赋值
2)派生类对象可以提到基类对象向基类对象的引用进行赋值或者初始化.
如已定义了基类A对象a1,可以定义a1的引用变量
A a1;//定义基类A对象a1
B b1;//定义公用派生类B对象b1
A &r = a1;//定义基类A对象的引用变量r,并哦那个a1对其初始化
这时,引用变量r是a1的别名,r和a1共享同一段储存单元。也可以用子类对象初始化引用变量r,将上面最后一行改为:
A &r = b1;//定义基类A对象的引用变量r,并用派生类B对象b1对其初始化
或者保留上面第3行"A &r = a1;",而对r重新赋值:
r = b1;//用派生类B对象b1对a1的引用变量r赋值
3)如果函数的参数是基类对象或者基类对象的引用,相应的实参可以用子类对象
4)派生类对象的地址可以赋给指向基类对象的指针变量,也就是说,指向基类对象的指针变量也可以指向派生类对象.
用指向基类对象的指针变量指向子类对象是合法的,安全的,不会出现遍以上的错误,但在应用上却不能完全满足人们的希望,人们有时希望通过使用基类指针能够基类和子类对象的成员。在下一章就要解决这个问题。办法是使用虚函数和多态性
分享到:
相关推荐
1 PartA2_SD Host_Controller_Simplified_Specification_Ver4.20 2 PartA2_SD_Host_Controller_Simplified_Specification_Ver2.00 3 PartE1_SDIO_Simplified_Specification_Ver2.00 4 PartE1_SDIO_Simplified_Specification_Ver3.00 5 Part1 PhysicalLayerSimplifiedSpecificationVer9.10Fin_20231201 6 PartE7_Wireless_LAN_Simplified_Addendum_Ver1.10 7 Part1_Extended_Security_Simplified_Addendum_Ver1.00 8 Part1_NFC_Interface_Simplified_Addendum_Ver1.00 9 Part1_UHS-II_Simplified_Addendum_Ver1.02 10 PartA1_ASSD_Extension_Simplified_Specification_Ver2.00 11 PartE2_SDIO Bluetooth_Type_A_Simplified_Specification_Ver1.00 12 SDUC-Host-Implementation-Guideline_Ver1.00
《步入元宇宙》由马克·范·里门撰写,是一本深入探讨元宇宙概念、历史、现状以及未来潜力的书籍。作者从Web 1.0到Web 3.0的发展讲起,详细分析了从增强现实(AR)到虚拟现实(VR)再到扩展现实(XR)的技术演进。书中提出了元宇宙的六大特征:互操作性、去中心化、持久性、空间性、社区驱动和自我主权,并强调了开放元宇宙的重要性及其带来的自由和创新潜力。作者还探讨了元宇宙对个人身份、商业、教育、娱乐等领域的深远影响,并预测了元宇宙将如何推动形成一个全新的社交经济。书中引用了多位行业专家的评价,强调了无论读者对元宇宙的了解程度如何,都能从中获得新的见解和启发。
卢益峰ads仿真放大器章节所需的ads库和MW6S004的ads模型
javaSE阶段面试题
《网页制作基础教程(Dreamweaver-CS6版)》第10章-网站的管理与上传.pptx
内容概要:本文详细介绍了如何使用Abaqus软件构建双线盾构隧道的超精细模型,特别是针对隧道间的联络通道、软化模量和盾构注浆等关键要素进行了深入探讨。文章首先阐述了模型的整体架构搭建,包括使用Python脚本创建隧道衬砌部件。接下来,讨论了软化模量的引入及其在材料本构模型中的定义方式,展示了如何通过塑性应变来模拟软化模量的变化。此外,文章详细讲解了盾构注浆的模拟方法,如通过单元生死技术激活注浆体单元,并提供了具体的Python代码示例。最后,文章强调了网格划分、接触设置等方面的注意事项,确保模型能够稳定运行并获得精确的结果。 适合人群:从事隧道工程数值模拟的研究人员和技术人员,尤其是熟悉Abaqus软件的工程师。 使用场景及目标:适用于需要进行双线盾构隧道工程力学行为研究的场合,旨在帮助工程师更好地理解和预测隧道施工过程中可能出现的问题,从而优化设计方案,提高施工效率和安全性。 其他说明:文中提供的代码片段和建模技巧基于作者的实际经验和测试结果,对于初学者而言,建议逐步尝试每个步骤并在实践中不断调整参数以适应具体工程项目的需求。
《自然资源信息化时代背景与发展》.pdf
《网络社会学(第2版)》15-网络社会变迁.ppt
内容概要:本文详细介绍了使用西门子1214PLC和KTP700Basic PN触摸屏构建双相机四轴多工位检测设备的具体实现方法。主要内容涵盖硬件配置、程序主体功能及其代码解析、触摸屏功能实现等方面。硬件方面,采用了西门子1214PLC作为核心控制器,KTP700Basic PN触摸屏为人机界面,双相机用于检测,第三设备通过Modbus RTU通讯。程序主体功能包括上下双工位4轴脉冲控制步进电机、与上位机双相机的TCP/IP通讯、与第三设备的Modbus RTU通讯。触摸屏功能则涉及多重画面、配方管理和密码保护等功能。文中还分享了一些调试经验和注意事项,如轴使能信号要用上升沿触发、相机通讯需配置心跳包机制等。 适合人群:从事工业自动化领域的工程师和技术人员,特别是那些对PLC编程、触摸屏应用和多工位检测设备感兴趣的读者。 使用场景及目标:适用于需要构建复杂自动化检测系统的工程项目,旨在提高检测效率和准确性,确保设备稳定可靠运行。通过学习本文,读者能够掌握如何使用西门子1214PLC和KTP700触摸屏搭建类似的检测系统。 其他说明:文中提供了大量具体的代码示例和调试技巧,有助于读者更好地理解和实施相关技术。此外,还强调了实际工程中常见的问题及解决方案,如接线和接地问题、通讯参数配置等。
- **4.4 版本** - 介绍了基础特性和标准,适合初学者了解eMMC的基本框架。 - **4.41 版本** - 对4.4版进行了修订和完善,优化了部分规范以适应市场和技术的发展。 - **4.5 版本** - 引入了新的性能改进和技术特性,进一步提升了存储效率。 - **4.51 版本** - 包含针对4.5版的小幅修正和增强,确保技术规范的准确性和实用性。 - **5.0 版本** - 重大更新,引入更多高级功能,支持更高的数据传输速率,对现代高性能需求进行了响应。 - **5.01 版本** - 在5.0基础上的维护更新,保持标准的一致性和先进性。 - **5.1 版本** - 最新的公开版本之一,提供了更全面的标准规范,加强了数据管理能力,提升了可靠性
DeepSeek系列-提示词工程和落地场景.pdf
JDK(java)安装及配置
内容概要:本文详细介绍了引力搜索算法(Gravitational Search Algorithm, GSA)的原理、MATLAB实现及其应用场景。首先解释了GSA的基本概念,即将优化问题中的候选解视为宇宙中互相吸引的粒子,通过模拟物理现象进行优化。接着展示了核心的粒子运动方程,包括加速度计算、质量分配以及引力公式的具体实现。文中提供了多个经典的测试函数如Sphere、Rastrigin等用于验证算法性能,并通过动态绘图展示了粒子群的收敛过程。此外,讨论了算法参数设置的影响,如引力常数G的指数衰减方式,以及如何通过添加随机扰动避免粒子陷入局部最优。最后强调了GSA在解决多峰优化问题方面的优势。 适合人群:对优化算法感兴趣的科研人员、学生及工程师,尤其是那些希望深入了解群体智能算法的人。 使用场景及目标:适用于需要高效寻找全局最优解的问题,特别是在面对复杂的多峰函数时。目标是帮助读者理解GSA的工作机制,掌握其MATLAB实现方法,并能够根据实际情况调整参数以获得更好的优化效果。 其他说明:尽管GSA在低维问题上有出色表现,但在高维优化问题中可能存在效率瓶颈,因此建议进一步研究并行计算或近似邻居搜索等改进措施。
基于Andorid的跨屏拖动应用设计实现源码,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。
DeepSeek R1 7b本地部署模型整合包及超全学习教程,资源总大小420G,喜欢的自行下载。
精品推荐,最新人工智能训练师认证资料汇总,15份。供大家学习参考。 (新版)人工智能训练师(中级)职业技能等级认定考试题库.pdf 2025年人工智能训练师(高级)职业技能鉴定参考题库(含答案).pdf 阿里认证高级人工智能训练师真题.pdf 初级人工智能训练师题库.pdf 高级人工智能化训练师认证答案解析.doc 高级人工智能训练师.docx 高级人工智能训练师题库.pdf 人工智能技术应用基础课件:人工智能训练师.pdf 人工智能训练师(服务机器人人工智能技术应用)(学生组)理论题库.pdf 人工智能训练师(服务机器人人工智能技术应用)理论题库.docx 人工智能训练师概述课件.pdf 人工智能训练师基础(上册).pdf 人工智能训练师技能等级认定四级理论知识试卷.docx 人工智能训练师试题及答案(150题).pdf 人工智能训练师职业技能标准.pdf
内容概要:本文探讨了Logistic函数在电力系统优化调度中的应用,特别是用于描述用户对电价变化的响应行为。文中详细介绍了Logistic函数如何通过S型曲线特性,将电价差与负荷转移率关联起来,形成死区、响应区和饱和区三个不同的响应阶段。此外,文章还展示了如何使用MATLAB进行仿真,以及在综合能源系统和微电网中的具体应用案例,如优化分时电价策略、设计需求响应激励机制等。 适合人群:电力系统研究人员、微电网调度工程师、能源管理专业学生。 使用场景及目标:适用于需要理解和应用需求响应模型的研究和工程项目,旨在提高电力系统的经济性和效率,优化调度策略。 其他说明:文章强调了模型的实际应用挑战,如参数调校、异常处理等,并提供了具体的MATLAB代码示例,帮助读者更好地理解和应用Logistic函数模型。
内容概要:本文档是一份C语言考核测试题,分为选择题和程序设计题两大部分。选择题部分共25题,涵盖C语言的基本概念、语法细节、运算符优先级、表达式求值、数据类型转换、控制结构等方面的知识点,旨在考察学生对C语言基础知识的理解与掌握。程序设计题部分提供了多个编程题目,如求数列和、阶乘之和、货币组合方式、质数与完数的求解、日期计算等,侧重于考察学生的实际编程能力和解决问题的能力。 适合人群:适合正在学习或复习C语言的学生,特别是计算机相关专业的本科生或高职高专学生。 使用场景及目标:①作为课堂练习或课后作业,帮助学生巩固所学知识;②作为考试或竞赛的模拟试题,评估学生对C语言的理解程度;③为教师提供教学参考,辅助课程设计与教学计划制定。 其他说明:建议考生在答题过程中仔细阅读题目要求,确保理解每个问题的具体含义。对于程序设计题,应先思考解决方案再动手编写代码,注意代码的规范性和可读性。同时,可以通过实际编译运行来验证程序的正确性。
《计算机系统维护》第1章--微型计算机简介.ppt
从官网下载了lvgl9.2.2模拟器项目,用VS2022运行的流程详解