继承

我们需要掌握以下知识点:

1.什么是继承?

2.继承权限和访问限定符

3.在public继承权限下,理解赋值兼容规则

4.继承中的作用域,理解什么是同名隐藏

5.派生类的默认成员函数

6.继承与友元

7.继承与static静态变量

8.继承体系下派生类的对象模型

什么是继承呢?

在C++中,所谓“继承”就是在一个已存在的类的基础上建立一个新的类。已存在的类称为“基类”或者“父类”

新建立的类称为“派生类”或者“子类”。

一个新类从已有的类那里获得其已有特性,称为类的继承。

从已有的类(父类)产生一个新的子类。称为类的派生。

拿生活中的例子来说,相当于说,你爸现在有两个矿场,你未来会从你爸手里接过矿场,即你继承了你爸的财产,你在未来会在此财产的基础上,继续发展,获得更多的财富。就这样,子子孙孙,无穷尽也。

关于继承权限和访问限定符

需要注意一下几点:

1.基类的private成员在派生类中是不能被访问的,如果基类成员不想在类外直接被访问,但需要在派生类中被访问,就定义为protected。

可以看出保护成员限定符是因继承才出现的。

2.public继承是一个接口继承,保持is-a原则,每个父类可用的成员对子类也可用,因为每个子类对象也都是一个父类对象,即:在所有用到基类对象的位置,都可用子类对象来代替。

3.无论哪种继承方式,在派生类内部都可以访问基类的公有成员和保护成员,基类的私有成员存在但是在子类中不可见(不能被访问)

4.使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。

5.在实际运用中一般都是public继承。

在public继承权限下,理解赋值兼容规则

在public继承权限下,子类和派生类对象之间有:

1.子类对象可以赋值给父类对象(切割)

2.父类对象不能赋值给子类对象

3.父类的指针/引用可以指向子类对象(******)

4.子类的指针/引用不能指向父类对象(可以通过强制类型转换完成,但可能会发生程序崩溃)

注意一下:根据对象模型的概念有助于理解赋值兼容原则:类中成员变量在内存中的布局形式。

继承中的作用域,理解什么是同名隐藏

1.在继承体系中,基类和派生类是两个不同的作用域

2.子类和父类有同名成员,子类成员将屏蔽父类对成员的直接访问(即同名隐藏)也就是说,用派生类对象去访问继承体系中的同名成员,只能访问到派生类自己的,基类的成员无法访问到,但是可以通过基类::基类成员 去访问。

派生类的默认成员函数

派生类继承了父类,那么会继承父类的六大默认成员函数吗?

1.构造函数: 
  派生类不会继承父类的构造函数! 
  派生类的构造函数属于合并构造函数,就是说他在执行自身的构造函数前,会先调用基类的构造函数完成它继承的基类成员的初始化,虽然你继承基类的成员,但是人家的成员初始化你得交给人家基类去做。所以说派生类执行自身的构造函数前,会先调用其基类的构造函数,如果他的基类还有父类,那么又先去调用基类的父类的构造函数,直到没有父类为止。这个调用构造函数的方式可以形象的看成一条链,也称为构造函数链。 

派生类中如果没有定义构造函数,编译器会自动生成一个默认构造函数。但是当父类的构造函数是有参、而子类没有显示调用父类的构造函数时,就会出错,所以建议一般将构造函数都写成缺省的方式,并且在子类中显示的去调用父类的构造函数。 

2.析构函数: 
  析构函数和构造函数恰好相反,会先调用子类的析构函数,再去调用父类的构造函数。注意:析构函数不用显示的去调用父类的析构函数,它会自己去调用父类的析构,不想构造函数那样需要显示的去调用父类的。 

3.拷贝构造函数: 
  拷贝构造函数也是构造函数,是特殊的构造函数,所以它也不会被继承,并且先调用父类的构造函数,再调用子类的拷贝构造

继承与友元

友元关系不能继承,因为友元类不是类的成员,也就是说,基类友元不能访问。

继承与static静态变量

继承体系下派生类的对象模型

1.单继承

对象模型如图所示:

2.多继承

3.菱形继承

菱形继承 = 单继承 + 多继承

其对象模型为:

菱形继承存在二义性,无法区分访问的是C1还是C2的_b,如何解决?

在当前,只有一种方法,就是加上作用域限定符。当然,下面介绍的菱形虚拟继承也可以很方便的解决这个问题。

4.虚拟继承

虚拟继承就是在基类前面加上virtual

class B//父类
{
    
}

class D: virtual public B//虚拟继承派生类
{
    
}

5.菱形虚拟继承(重要)

派生类对象模型

注意:对比虚拟继承&单继承

1.多出4个字节---地址---偏移量表格

2.派生类对象模型:基类在下,派生类在上

3.派生类对象访问基类成员--->通过偏移量表格地址

4.合并构造函数,并且多传递  '1'--->检测是否为虚拟继承

                 在构造对象期间,将偏移量表格的地址放在对象的前四个字节。

 

总结常见题型:

1.什么是继承?

2.什么是菱形继承?菱形继承有什么缺陷?

3.什么是菱形虚拟继承?为什么使用菱形虚拟继承可以解决菱形继承存在的问题?

4.继承体系中,基类哪些成员被派生继承了?友元可以继承吗?

5.设计一个类,该类不能被继承(思路:私有构造方法+静态成员函数)

注意:在C++11中,还可以使用final关键字来达到效果。

6.用C语言模拟实现继承

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值