在线个人资料制作网站建设部人事司网站

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

在线个人资料制作网站,建设部人事司网站,常州制作网站,中国国际贸易网官网平台一 、继承 1 继承的概念 继承是面向对象程序设计使得代码可以复用的最重要手段#xff0c;它使得我们可以在原有类的特性的基础上进行扩展#xff0c;增加方法和属性#xff08;成员函数与成员变量#xff09;#xff0c;这样产生新的类#xff0c;叫作派生类。继承呈现了…一 、继承 1 继承的概念 继承是面向对象程序设计使得代码可以复用的最重要手段它使得我们可以在原有类的特性的基础上进行扩展增加方法和属性成员函数与成员变量这样产生新的类叫作派生类。继承呈现了面向对象程序设计的层次结构体现了由简单到复杂的认知过程。以前我们学习的实在函数上的复用现在我们一起来学习在类上的复用吧 1. 样例示范  下面我们设计两个类一个是Student类一个Teacher类 可以看到这两个类中有大量重复的如姓名地址等的成员变量设计到两个类里面是冗余的当然他们 也有⼀些不同的成员变量和函数比如老师独有成员变量是职称学生的独有成员变量是学号但是如果我们能定义一个新类叫Person类将这些冗余的成员变量放进去然后通过某种方式使得Student类和Teacher类能获得这些成员变量那就使得复用率大大提高这种方式就是继承。 2 继承定义 1.定义格式 派生类类名 继承方式  基类 Student就是派生类类名 继承方式是public  基类父类是Person 2.继承方式 1                 2继承访问方式的变化 基类private成员在派生类中无论以什么方式继承都是不可⻅的。这⾥的不可见是指基类的私有成员 还是被继承到了派⽣类对象中但是语法上限制派⽣类对象不管在类里面还是类外面都不能去访问它。基类private成员在派⽣类中是不能被访问如果基类成员不想在类外直接被访问但需要在派⽣类 中能访问就定义为protected。可以看出保护成员限定符是因继承才出现的实际上⾯的表格我们进⾏⼀下总结会发现基类的私有成员在派⽣类都是不可⻅。基类的其他成员 在派⽣类的访问⽅式Min(成员在基类的访问限定符继承⽅式)public protected private使⽤关键字class时默认的继承⽅式是private使⽤struct时默认的继承⽅式是public不过最好显 ⽰的写出继承⽅式。在实际运⽤中⼀般使⽤都是public继承⼏乎很少使⽤protetced/private继承也不提倡使⽤ protetced/private继承因为protetced/private继承下来的成员都只能在派⽣类的类⾥⾯使⽤实 际中扩展维护性不强 3 基类与派生类之间的转化 3.1 public继承的派生类对象可以赋值给基类的指针或者基类的引用这里有个形象的说法叫做切片相当于吧派生类中属于基类的那一部分切割出来给到基类的指针或者基类的引用注意只有public继承才行(注意这里没有隐式类型转化) 样例 3.2 基类不能赋值给派生类 3.3 基类的指针和引用可以通过强制类型转换给派生类的指针和引用 但是必须是基类的指针是指向对应的派生类对象时才是安全的 4.继承的作用域  规则 在继承中基类和派生类都有其单独的作用域基类和派生类中有同名成员成员变量/成员函数派生类将屏蔽基类的实现只调用派生类的实现这里叫做隐藏/重定义注意这里不是函数的重载了函数的重载必须在相同作用域查找规则由于隐藏查找先找子类 - 父类 - 全局域从这里也能看出基类的成员函数并不是在派生类中重新写一个而是子类找不到去父类里找更何况如果是写到子类里那就有两个同名函数在同一作用域里编译语法不过的隐藏规则注意这里只要函数名相同就构成隐藏关系在派⽣类成员函数中可以使⽤基类::基类成员显⽰访问基类成员 样例

  1. 2. 这样编译不过因为只要函数名相同就构成重写只能访问到子类的fun(). 5 派生类的默认成员函数 5.1  四个常用的默认成员函数 6个默认成员函数默认的意思就是指我们不写编译器会变我们⾃动⽣成⼀个那么在派⽣类中这 ⼏个成员函数是如何⽣成的呢 1构造函数 派生类的实例化过程是先创建父类再创建子类因为在子类初始化的过程可能会用到父类的成员派生类的构造过程必须先调用基类的构造函数初始化基类的那一部分成员。如果基类没有默认构造函数你已经显示写了基类的构造函数则必须在派生类的初始化列表阶段显示调用基类的构造函数 示例 1.Person调用默认构造 2. Person构造显示调用 若此时没有显示调用基类构造编译器语法报错  通过输出发现先调用基类构造再走派生类初始化列表 此时将st正确初始化 2拷贝构造函数 派生类调用拷贝构造函数必须调用基类的拷贝构造函数若是仅涉及浅拷贝那就不用显示写使用基类的默认拷贝构造即可可若是涉及深拷贝有资源申请那就不能让编译器一个一个进行值拷贝了得显示写基类的拷贝构造函数在派生类的拷贝构造显示调用基类的拷贝构造 样例 拷贝构造也是构造也可以用初始化列表  3派生类的operator 必须调用基类的operator完成基类的复制。需要注意的是派⽣类的 operator隐藏了基类的operator所以显⽰调⽤基类的operator需要指定基类作⽤域 4析构函数  首先在对象的析构中派生类的析构函数会在被调⽤完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。没有资源申请不用显式写因为多态中⼀些场景析构函数需要构成重写重写的条件之⼀是函数名相同(这个我们多态章节会讲解)。那么编译器会对析构函数名进行特殊处理处理成destructor()所以基类析构函数不加 virtual的情况下派生类析构函数和基类析构函数构成隐藏关系。 6.实现一个不能被继承的类  方法1基类的构造函数私有派生类的构成必须调用基类的构造函数但是基类的构成函数私有化以后派生类看不见就不能调用了那么派生类就无法实例化出对象。 方法2C11新增了⼀个final关键字final修改基类派⽣类就不能继承了。 示例 直接在基类的类名后加final关键字即可  7 继承和友元以及静态成员 1.继承和友元 友元不能继承基类的友元不是子类的友元也就是说基类友元不能访问派生类私有和保护成员 2.继承与静态成员 基类定义了static静态成员则整个继承体系⾥⾯只有⼀个这样的成员。无论派生出多少派生类都只有一个static成员 8.菱形继承 1.继承模型 再说菱形继承之前先说一下继承的分类继承可以分为单继承与多继承 单继承⼀个派生类只有⼀个直接基类时称这个继承关系为单继承我们之前写的全是单继承 多继承⼀个派⽣类有两个或以上直接基类时称这个继承关系为多继承多继承对象在内存中的模型 是先继承的基类在前⾯后⾯继承的基类在后⾯派生类成员在放到最后面 菱形继承菱形继承是一种多继承 菱形继承是多继承的⼀种特殊情况。菱形继承的问题从下⾯的对象成员模型构造可以 看出菱形继承有数据冗余和⼆义性的问题在Assistant的对象中Person成员会有两份  需要显⽰指定访问哪个基类的成员可以解决⼆义性问题但是数据冗余问题⽆法解决 这就引入了虚继承 9.虚继承 很多⼈说C语法复杂其实多继承就是⼀个体现。有了多继承就存在菱形继承有了菱形继承就有 菱形虚拟继承底层实现就很复杂性能也会有⼀些损失 使用虚继承问题解决virtual使用位置在将产生二义性/数据冗余的上一位置