C++课件第十一章继承和派生类_第1页
C++课件第十一章继承和派生类_第2页
C++课件第十一章继承和派生类_第3页
C++课件第十一章继承和派生类_第4页
C++课件第十一章继承和派生类_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第十一章继承和派生类C++面向对象程序设计核心机制Contents课程目录C++继承与多态核心知识体系,从基础概念到高级机制的系统学习路径。01继承的基本概念与意义02继承方式与访问控制03构造析构与初始化机制04同名隐藏与多继承05虚基类与多态机制06实训总结与进阶展望Chapter01继承的基本概念与意义理解面向对象复用机制的起点Chapter04·Object-OrientedProgramming什么是继承继承是面向对象程序设计三大特性之一,它允许派生类复用基类的已有属性和成员函数,并在此基础上扩展新功能,从而实现代码复用与类层级结构的建立。C++编程环境中的代码界面01复用与扩展允许派生类复用基类的已有属性和成员函数,并在此基础上扩展新功能02共性与个性基类提供已有成员和方法,派生类继承的同时新增自己的特有成员03C++类层级顶层类即为最终基类,没有统一根类,类层级由程序员自行设计04结构清晰类与类之间形成明确的层级关系,便于后期功能扩展与代码维护INHERITANCE继承的三大核心作用继承机制从代码复用、结构设计和功能扩展三个维度提升了程序的可维护性和开发效率,是面向对象设计从"能用"走向"好用"的关键桥梁。软件开发团队协作CODEREUSE派生类直接继承基类已有的属性和方法,避免重复编写相同逻辑,显著减少代码量并降低出错概率HIERARCHY通过父子类的继承链条形成清晰的分类体系,使程序结构更符合人类对现实世界的认知方式OPEN-CLOSED在不修改基类代码的前提下,通过派生类添加新功能或重写已有功能,遵循开闭原则EFFICIENCY基类可单独编译,修改基类实现时只要公用接口不变,派生类不必重新编译,大幅提升大型项目的编译效率C++Inheritance继承的语法格式C++中派生类的声明通过冒号语法指定继承方式与基类名称,派生类成员包含从基类继承的共性成员和自身新增的个性成员两部分,语法简洁但语义丰富。01基本语法格式为class派生类名:继承方式基类名{新增成员},冒号是C++继承语法的核心标志Syntax02继承方式有三种选择:public(公有继承)、protected(保护继承)和private(私有继承),不写时默认为privateAccess03派生类中的成员包含两大部分:从基类继承过来的成员体现共性,自己新增的成员体现个性Members04classStudent:publicPerson表示Student公有继承Person,自动拥有Person的非私有成员并可新增自己的属性和方法ExampleChapter02继承方式与访问控制掌握三种继承方式的权限变化规律ACCESSCONTROL基类的三种访问修饰符C++类成员的三种访问修饰符(private、protected、public)构成了访问控制的基础层级,它们在继承场景下的行为差异是理解三种继承方式权限变化的前提。01private(私有成员):只能被基类自身的成员函数访问,派生类完全不可见,相当于类内部的"密室",外部世界和子类都无法直接触及类内部密室02protected(保护成员):本类和所有派生类均可访问,但类的外部不可访问,是专门为继承设计的"家族共享空间",兼顾封装性与继承性家族共享空间03public(公有成员):对所有外部代码完全公开访问,是类对外提供的接口,任何对象和函数都可以通过对象名直接调用对外接口04理解口诀:private是自己独享,protected是家族共享,public是对外开放——继承方式在此基础上进一步调整权限边界权限口诀C++继承机制三种继承方式的权限变化C++的三种继承方式遵循"权限只缩不扩,私有始终不可见"的核心规则:公有继承保持原权限不变,保护继承统一收缩为protected,私有继承统一收缩为private,而基类的private成员在任何继承方式下都对派生类不可见。PublicInheritancepublic公有继承父类的public成员在子类中仍为public,protected成员仍为protected,权限保持不变父类的private成员子类无法直接访问,这是C++封装性的底线,任何继承方式都无法突破最常用ProtectedInheritanceprotected保护继承父类的public和protected成员在子类中全部变为protected,对外访问权限被收缩适用于基类只希望被家族内部(子类链)使用、不对外暴露的场景权限收缩PrivateInheritanceprivate私有继承父类的public和protected成员在子类中全部变为private,子类外部使用者完全无法访问不写继承方式时C++默认为private继承,实际开发中极少使用,推荐显式写明默认方式AccessControl继承权限对照速查表通过权限对照表可以直观看到:公有继承保持权限不变,保护继承将公有成员降级为保护,私有继承将所有可继承成员降级为私有,而基类私有成员在任何继承方式下均不可访问。三种继承方式下的权限变化对照基类成员原始权限public继承后protected继承后private继承后publicpublicprotectedprivateprotectedprotectedprotectedprivateprivate不可访问不可访问不可访问01公有继承保持基类成员的原始权限等级不变,是实际开发中最常用的继承方式,适合表达"is-a"关系02保护继承和私有继承会收缩权限,适用于不希望派生类外部用户访问基类接口的特殊场景03基类的private成员在三种继承方式下均显示为"不可访问",验证了"私有始终不可见"的核心规则权限只缩不扩,私有始终不可见——这是三种继承方式的统一规则C++INHERITANCE继承中的访问规则与易错点继承中的访问控制不仅涉及权限变化表,还包括构造/析构函数不可继承、protected成员的访问边界、以及基类构造函数的调用约束等细节,这些是实际编程和考试中的高频易错点。构造与析构函数不可继承子类不能继承父类的构造函数和析构函数,只能调用它们——构造函数负责初始化,每个类必须用自己的构造函数完成初始化工作。初始化独立protected的访问边界protected成员在子类内部可直接访问,但在子类外部通过对象名访问仍然不允许,它的开放范围仅限于"家族内部"。家族内部可见private成员的间接访问基类的private成员虽然子类不可直接访问,但可以通过基类提供的public或protected接口函数间接访问其值。接口间接访问基类构造函数的调用约束如果基类没有无参构造函数,子类必须在初始化列表中显式调用基类的有参构造函数,否则编译器会报错。显式调用必须CHAPTER03构造析构与初始化机制掌握继承体系中对象生命周期管理的核心规则C++ObjectLifecycle构造与析构的执行顺序继承体系中对象的构造遵循'先父后子'、析构遵循'先子后父'的固定顺序,这是C++编译器强制规定的生命周期管理规则。01构造顺序:先调用父类构造函数初始化基类部分,再调用子类构造函数初始化派生类新增部分,保证"地基先于楼房"构造→自顶向下02析构顺序:先调用子类析构函数清理派生类资源,再调用父类析构函数清理基类资源,遵循"后建先拆"原则析构→自底向上03记忆口诀:"先父后子(构造),先子后父(析构)",构造与析构顺序完全相反,符合栈式资源管理的通用逻辑栈式LIFO04编译器强制:这一顺序由编译器强制执行,程序员无法通过代码改变,对避免资源泄漏和野指针至关重要不可覆盖地基先于楼房·类比继承中基类先于派生类构造C++继承·构造函数子类初始化父类参数当基类构造函数需要参数时,派生类必须通过初始化列表显式调用基类的有参构造函数,这是C++继承体系中参数传递的唯一合法路径,遗漏将导致编译错误。01语法格式Son(参数列表):Father(参数){},冒号后的初始化列表是向父类构造函数传递参数的唯一方式。SYNTAX02强制显式调用父类没有无参构造函数时,子类必须在初始化列表中手动调用父类的有参构造函数,否则编译报错。MANDATORY03自动隐式调用父类有无参构造函数且子类未显式调用任何父类构造时,编译器会自动调用父类的无参构造函数。AUTO04初始化差异派生类新增成员可在构造函数体内赋值,但基类部分只能通过初始化列表完成初始化。DIFFERENCEC++·Inheritance多重继承的构造顺序多继承场景下,各基类构造函数的调用顺序严格按照派生类声明时基类的书写顺序从左到右依次执行,与初始化列表中的书写顺序无关,析构顺序则完全相反。01核心规则:多继承的构造顺序按声明继承时基类的书写顺序从左到右依次调用各基类构造函数,最后执行派生类自身构造函数。这一机制确保了对象构建的确定性和可预测性。声明顺序从左到右02典型示例:classD:publicB1,publicB2,publicB3的构造顺序为B1→B2→B3→D,析构顺序则完全相反为D→B3→B2→B1。构造与析构形成完美的对称关系。构造析构相反03常见误区:构造顺序取决于类声明头部的基类书写顺序,而非初始化列表中的排列顺序。许多初学者误以为初始化列表的顺序决定构造顺序,这是需要特别注意的认知陷阱。声明顺序优先非初始化列表04语法格式:派生类构造函数的初始化列表格式为D(总参数):B1(参数),B2(参数),B3(参数){},每个基类分别接收所需参数,实现灵活的参数传递机制。参数传递独立初始化CHAPTER04同名隐藏与多继承处理继承体系中的命名冲突与复杂层级关系C++INHERITANCE同名隐藏规则当派生类与基类存在同名成员变量或同名函数时,派生类成员会隐藏基类的同名内容,默认访问的是派生类自身成员;若要访问被隐藏的基类成员,必须使用作用域限定符'基类名::'显式指定。同名隐藏触发条件子类和父类出现同名的成员变量或同名函数时,子类自动隐藏父类的同名内容,默认访问子类自身成员。自动隐藏作用域限定符访问访问被隐藏的父类成员需使用作用域限定符,语法为父类名::成员名,例如Father::show()调用父类被隐藏的函数。Father::show()名称查找规则同名隐藏由C++名称查找规则决定:编译器先在当前类(子类)中查找名称,找到后就不再向上层基类查找。编译时决定与虚函数重写的区别同名隐藏是静态绑定(编译时决定),虚函数重写是动态绑定(运行时决定),两者机制完全不同。静态vs动态C++Inheritance同名隐藏的代码示例同名隐藏在实际代码中表现为子类对象默认调用自身版本,父类版本需通过作用域限定符显式调用;即使参数列表不同也会触发隐藏而非重载。基本示例父类Father有show()输出"我是父类",子类Son也有show()输出"我是子类",调用son.show()时执行子类版本。作用域限定符通过son.Father::show()可显式调用被隐藏的父类版本,作用域限定符是穿透同名隐藏的唯一手段。参数陷阱即使父类show()无参、子类show(int)有参,仍触发同名隐藏而非重载——C++先按名称查找,找到后不再考虑参数匹配。Using声明解决若需在子类中同时提供父类和子类的同名函数版本,可使用usingFather::show;声明将父类版本引入子类作用域。C++Inheritance继承的三种分类C++支持单继承、多继承和多层继承三种层级结构,其中单继承最安全常用,多继承功能强大但易产生二义性,多层继承形成链式传递,三者各有适用场景。单继承一个派生类只从一个基类派生,结构清晰、不易出错,是实际开发中最推荐的继承方式。绝大多数面向对象设计需求都可以通过单继承配合组合模式来实现。最安全·推荐首选多继承一个派生类同时拥有两个或多个基类,可复用多个来源的功能,但易产生二义性和菱形继承问题。能用单一继承解决的问题就不要使用多重继承,仅在确实必要时才考虑。功能强·慎用多层继承形成父类→子类→孙子类的链式继承结构,属性和方法逐级传递,每一层都可以新增或重写成员。构造函数从最顶层基类开始逐层向下执行,析构则从最底层逐层向上。链式传递C++Inheritance多继承的二义性问题多继承中最突出的问题是二义性——当多个基类存在同名成员时编译器无法判断调用目标,以及菱形继承导致公共基类产生多份拷贝浪费内存,需要分别通过作用域限定符和虚基类来解决。二义性场景当多个基类存在同名数据或函数时,派生类对象直接访问会产生歧义,编译器将报错拒绝编译。AmbiguityError解决方案一使用类作用域符号::显式指明访问哪个基类的成员,例如d.B::show()明确调用基类B的版本。ScopeResolution菱形继承问题同一个公共基类在多层多继承的派生类中产生多个拷贝,既多占用内存空间又容易导致数据不一致。DiamondProblem解决方案二将公共基类声明为虚基类,确保在最终派生类中只保留一份基类拷贝,彻底解决菱形继承的数据冗余问题。VirtualBaseClassChapter05虚基类与多态机制从菱形继承到动态绑定,掌握C++面向对象的高级特性VirtualBaseClass虚基类的概念与语法虚基类通过在继承声明中添加virtual关键字解决菱形继承中的多份拷贝问题,确保公共基类在最终派生类中只保留唯一实例,从而消除数据冗余和二义性。01虚基类的作用在多重派生过程中,若使公共基类在派生类中只有一个拷贝,可将公共基类说明为虚基类02语法格式在派生类定义的基类名前加上关键字virtual,例如classB:virtualpublicA{},声明A为B的虚基类03虚基类对象的初始化由虚基类派生出的对象初始化时,直接调用虚基类的构造函数,中间层类的构造函数中对虚基类的调用被忽略04使用原则能用单一继承解决的问题就不要使用多重继承,仅在简单、不易出现二义性的情况或确实必要时才考虑虚基类POLYMORPHISM多态的基本概念与分类多态是指向不同对象发送同一消息时产生不同行为的机制,C++支持编译时的静态多态和运行时的动态多态,其中动态多态是面向对象设计的核心支柱。核心定义向不同对象发送同一消息产生不同行为——同一接口、多种实现,面向对象灵活性的源泉。同一接口静态多态编译时多态:函数重载与运算符重载,编译器根据参数类型和数量确定调用版本。编译时动态多态运行时多态:通过虚函数实现,根据对象实际类型动态决定调用哪个函数版本。运行时设计意义基类指针统一操作不同派生类对象,实现"一个接口、多种形态"的灵活设计。多形态C++Polymorphism虚函数的定义与规则虚函数是用virtual关键字修饰的基类非private成员函数,它允许在派生类中被重新定义以形成不同版本,是实现运行时多态的基础设施;使用虚函数多态必须通过基类指针或引用调用。01虚函数定义:用关键字virtual修饰的基类中非private成员函数,可在派生类中重新定义以形成不同版本,例如virtualfloatarea(){return0.0;}02重写要求:派生类中定义的虚函数必须与基类虚函数同名,参数类型、顺序、个数及返回类型必须一一对应,否则无法正确覆盖03调用方式:必须使用基类类型的指针变量指向派生类对象,通过指针调用虚函数才能实现多态;通过对象名访问只能静态绑定04约束条件:虚函数必须是类的成员函数,不能是友元或静态成员函数;构造函数不能为虚函数,但析构函数可以且建议为虚函数编程学习·虚函数与运行时多态C++VIRTUALPOLYMORPHISM虚函数多态的实现细节虚函数多态必须通过基类指针或引用调用才能触发动态绑定;C++通过虚函数表实现运行时灵活性,但也影响执行效率。01多态触发条件p->method()p.method()必须使用基类指针指向派生类对象并通过指针调用,即p->method()形式,不能是p.method()的对象名直接调用。这是C++静态类型系统与动态行为结合的关键语法点。02动态绑定机制C++通过虚函数表(vtable)实现运行时方法查找,每个含虚函数的类都有一张vtable,对象创建时绑定到对应版本。这种设计让编译器能够在编译期确定虚表布局,运行期仅需一次间接跳转。03性能代价多态的动态绑定比静态绑定多一次指针间接寻址,影响执行效率,因此C++要求程序员主动声明virtual而非默认启用。这种显式选择体现了C++零开销抽象的设计哲学。04常见错误忘记在基类中声明virtual导致无法多态、派生类重写时参数列表不一致导致形成新函数而非覆盖,是最常见的两类bug。建议使用override关键字进行编译期检查以避免此类问题。C++BestPractice虚析构函数的必要性当通过基类指针删除派生类对象时,若基类析构函数非虚则只调用基类析构函数导致派生类资源泄漏,因此基类析构函数一般应声明为virtual以确保完整的析构链被执行。01问题场景通过基类指针delete派生类对象时,若基类析构函数非virtual,编译器只调用基类析构函数,派生类析构函数被跳过02后果严重派生类中动态分配的资源(如new出来的内存、打开的文件句柄)无法被释放,造成内存泄漏和资源泄漏03解决方案将基类的析构函数声明为virtual,确保delete时按"先子后父"的完整析构链执行,所有层级的资源都被正确清理04最佳实践只要一个类有可能被继承,就应该将其析构函数声明为virtual——这是一个低成本高收益的防御性编程习惯C++OBJECT-ORIENTED纯虚函数与抽象类纯虚函数是没有实现的虚函数(以=0标记),它定义了派生类必须遵循的接口规范;含有纯虚函数的类称为抽象类,不能实例化对象,只能作为基类提供接口框架。纯虚函数语法在虚函数声明末尾加=0,如virtualvoiddraw()=0,表示该函数没有实现体,仅定义接口规范=0抽象类定义含有至少一个纯虚函数的类称为抽象类,抽象类不能创建对象实例,只能作为基类被派生类继承不可实例化派生类义务派生类必须实现所有继承的纯虚函数,否则派生类本身也变成抽象类,仍然无法实例化强制实现设计意义抽象类定义了"是什么"和"能做什么"的契约,派生类负责"怎么做"的具体实现,实现接口与实现分离契约式设计Chapter06实训总结与进阶展望梳理继承知识体系,为多态深入学习做好准备ChapterReview本章核心知识点回顾继承和派生类章节涵盖从基础语法到高级机制的完整知识体系,包括继承概念与语法、三种继承方式的权限变化、构造析构顺序、同名隐藏规则、多继承与虚基类、以及虚函数与多态六大核心模块。基础

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论