0712学习总结(派生类,继承)

1.继承权限
1.public继承方式基类中所有 public 成员在派生类中为 public 属性;基类中所有 protected 成员在派生类中为 protected 属性;基类中所有 private 成员在派生类中不能使用
2.protected继承方式
基类中的所有 public 成员在派生类中为 protected 属性;
基类中的所有 protected 成员在派生类中为 protected 属性;
基类中的所有 private 成员在派生类中不能使用。
3.private继承方式
基类中的所有 public 成员在派生类中均为 private 属性;
基类中的所有 protected 成员在派生类中均为 private 属性;
基类中的所有 private 成员在派生类中不能使用

在派生类中访问private的方法:
1.借助基类的非 private 成员函数
2.如果基类没有非 private 成员函数,那么该成员在派生类中将无法访问


2.改变访问权限
使用 using 关键字可以改变基类成员在派生类中的访问权限,例如将 public 改为 private
例子:
using people::m_name;
using people::m_age;

3.名字遮蔽
什么是遮蔽?
1.如果派生类中的成员(包括成员变量和成员函数)和基类中的成员重名,那么就会遮蔽从基类继承过来的成员。
2.所谓遮蔽,就是在派生类中使用该成员(包括在定义派生类时使用,也包括通过派生类对象访问该成员)时,实际上使用的是派生类新增的成员,而不是从基类继承来的
注意:
1.基类成员函数和派生类成员函数不构成重载
2.基类成员和派生类成员的名字一样时会造成遮蔽
3.成员函数要引起注意,不管函数的参数如何,只要名字一样就会造成遮蔽。
4.换句话说,基类成员函数和派生类成员函数不会构成重载,如果派生类有同名函数,那么就会遮蔽基类中的所有同名函数,不管它们的参数是否一样。 


4.派生类的构造函数
1.类的构造函数不能被继承。
2.构造函数不能被继承是有道理的,因为即使继承了,它的名字和派生类的名字也不一样,不能成为派生类的构造函数,当然更不能成为普通的成员函数。
3.在设计派生类时,对继承过来的成员变量的初始化工作也要由派生类的构造函数完成,但是大部分基类都有 private 属性的成员变量,它们在派生类中无法访问,更不能使用派生类的构造函数来初始化。

构造函数的调用顺序:
基类构造函数总是被优先调用,这说明创建派生类对象时,会先调用基类构造函数,
    再调用派生类构造函数,如果继承关系有好几层的话,
例如:A --> B --> C
那么创建 C 类对象时构造函数的执行顺序为:
    A类构造函数 --> B类构造函数 --> C类构造函数

注意:
1.构造函数的调用顺序是按照继承的层次自顶向下、从基类再到派生类的。
2.派生类构造函数中只能调用直接基类的构造函数,不能调用间接基类的。


5.基类构造函数调用规则
1.通过派生类创建对象时必须要调用基类的构造函数,这是语法规定。
2.换句话说定义派生类构造函数时最好指明基类构造函数;
3.如果不指明,就调用基类的默认构造函数(不带参数的构造函数);如果没有默认构造函数,那么编译失败。

6.派生类的析构函数
1.和构造函数类似,析构函数也不能被继承。
2.与构造函数不同的是,在派生类的析构函数中不用显式地调用基类的析构函数,因为每个类只有一个析构函数,编译器知道如何选择,无需程序员干涉
3.另外析构函数的执行顺序和构造函数的执行顺序也刚好相反:
4.创建派生类对象时,构造函数的执行顺序和继承顺序相同,即先执行基类构造函数,再执行派生类构造函数。
5.而销毁派生类对象时,析构函数的执行顺序和继承顺序相反,即先执行派生类析构函数,再执行基类析构函数

7.C++的多继承类
多继承的语法也很简单,将多个基类用逗号隔开即可。
例如已声明了类A、类B和类C,那么可以这样来声明派生类D:
class D: public A, private B, protected C{   //类D新增加的成员}


D 是多继承形式的派生类,它以公有的方式继承 A 类,以私有的方式继承 B 类,以保护的方式继承 C 类。D 根据不同的继承方式获取 A、B、C 中的成员,确定它们在派生类中的访问权限。


8.多继承下的构造函数
1.多继承形式下的构造函数和单继承形式基本相同,只是要在派生类的构造函数中调用多个基类的构造函数。
2.基类构造函数的调用顺序和和它们在派生类构造函数中出现的顺序无关,而是和声明派生类时基类出现的顺序相同。


9.命名冲突:
当两个或多个基类中有同名的成员时,如果直接访问该成员,就会产生命名冲突,编译器不知道使用哪个基类的成员。
这个时候需要在成员名字前面加上类名和域解析符::,以显式地指明到底使用哪个类的成员,消除二义性。

10.虚继承和虚基数
多继承时很容易产生命名冲突,即使我们很小心地将所有类中的成员变量和成员函数都命名为不同的名字,命名冲突依然有可能发生,比如典型的是菱形继承。

虚继承:
1.在继承方式前面加上 virtual 关键字就是虚继承
2.虚继承的目的是让某个类做出声明,承诺愿意共享它的基类。
3.其中,这个被共享的基类就称为虚基类(Virtual Base Class),本例中的 A 就是一个虚基类。
4.在这种机制下,不论虚基类在继承体系中出现了多少次,在派生类中都只包含一份虚基类的成员。

小结:
1.在虚继承中:虚基类是由最终的派生类初始化的,换句话说,最终派生类的构造函数必须要调用虚基类的构造函数。
2.对最终的派生类来说,虚基类是间接基类,而不是直接基类。
3.这跟普通继承不同,在普通继承中,派生类构造函数中只能调用直接基类的构造函数,不能调用间接基类的

注意:
c++规定必须由最终的派生类 D 来初始化虚基类 A,直接派生类 B 和 C 对 A 的构造函数的调用是无效的

构造函数的执行顺序:
虚继承时构造函数的执行顺序与普通继承时不同:
1.在最终派生类的构造函数调用列表中,不管各个构造函数出现的顺序如何,编译器总是先调用虚基类的构造函数,再按照出现的顺序调用其他的构造函数;
2.对于普通继承,就是按照构造函数出现的顺序依次调用的



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值