C++学习:封装,继承和多态 封装继承和多态封装类是封装的核心继承继承方式和访问限定符继承规则继承的问题继承还是组合多态编译时多态和运行时多态虚函数纯虚函数和抽象类了解概念理解封装类是封装的核心类通过成员变量和成员函数将数据和功能绑定通过访问限定符实现访问权限控制至此每一个类都实现特定功能都是一个模块相互解耦。继承继承方式和访问限定符基类的访问限定符和派生类的继承方式共同决定继承得来的成员的访问权限继承规则隐藏关系当基类成员和派生类成员同名会构成隐藏关系基类同名成员会被隐藏派生类对象可以赋值给基类指针/引用/对象基类对象不可赋值给派生类指针/引用/对象Student stu;//派生类Person ppstu;//相当于从派生类对象分割出基类对象Person*p1stu;Personp2stu;派生类构造和析构派生类构造需要调用基类构造函数若无默认构造则需要在初始化列表中显示调用基类拷贝构造需要在初始化列表中调用Student(Studentstu):Person(stu){//深拷贝}派生类析构函数调用顺序构造时派生类初始化可能依赖基类成员需要先初始化基类才能使用基类方法析构时派生类析构可能依赖基类成员需要先进行派生类析构防止基类先析构导致访问出错友缘关系不可继承基类的友缘不可直接访问派生类的私有和保护成员基类定义static变量全局唯一无论有多少派生类在继承体系中只有唯一一个static实例继承的问题菱形继承在多继承场景下可能会出现这种场景此时会出现数据冗余和二义性1.Assistant会有多个Person对象 2.两个Person类需要确定操作对象解决方法采用以下形式进行指定对象数据冗余为解决a.Student::_nameyyy;a.Teacher::_namexxx;虚继承classStudent:virtualpublicPerson虚继承会将公共类单独放置最后调用构造继承还是组合继承内部可见依赖程度高耦合度高组合内部不可见依赖程度低耦合度低就比如一个基类有90个私有成员10个公有成员如果采用继承内存中会包含所有基类成员基类发生修改可能会影响到派生类组合只会感知到这10个成员围绕着这10个成员访问耦合度降低。多态编译时多态和运行时多态编译时多态函数重载和函数模版实参传参进行参数匹配是在编译时进行的运行时多态对于某一行为函数传入不同参数完成不同行为条件1.必须是基类的指针或者引用调用虚函数2.被调函数必须是虚函数并且完成虚函数的重写/覆盖虚函数虚函数是实现运行时多态的基础对虚函数进行重写从而达到多态virtualvoidfunc(){}//虚函数虚函数表和虚函数表指针对于存在虚函数virtual的类会生成一张虚函数表虚函数表中会记录所有虚函数地址同类对象会共用一张虚函数表派生类会继承基类的虚函数表并对重写的虚函数进行地址覆盖添加派生类虚函数地址虚函数表指针则是指向虚函数表的指针传入不同参数完成不同实现多态的实现是通过调用传入参数的虚函数表指针所指向不同虚表对应函数实现的注析构函数在编译时会统一命名为destructor导致派生类析构和基类析构形成隐藏关系一般需要加上virtual纯虚函数和抽象类包含纯虚函数的类为抽象类纯虚函数一般不需要定义因为抽象类不可实例化classConnnect{public:vritualvoidfunc()0;//函数定义后0表示虚函数};了解多态控制override希望多态重写没有报错如名字拼写错误final不允许重写虚函数概念理解重载1.在同一作用域2.函数名相同参数不同参数个数或类型不同返回值同或不同重写/覆盖1.函数分别在基类和派生类两个不同的作用域中2.函数名参数返回值都相同协变例外3.函数必须为虚函数隐藏1.函数分别在基类和派生类两个不同的作用域中2.函数名相同3.不是重写就是隐藏4.基类和派生类的同名成员变量也构成隐藏关系没有形成多态同名函数构成隐藏基类指针只会调用基类成员函数派生类指针只会调用派生类成员函数